From 4fd59d1bba9885216504416044f51890695b1e31 Mon Sep 17 00:00:00 2001 From: caspersimon <165684406+caspersimon@users.noreply.github.com> Date: Mon, 23 Mar 2026 17:12:31 +0100 Subject: [PATCH 1/6] add RTK.md --- .DS_Store | Bin 14340 -> 14340 bytes AGENTS.md | 2 ++ RTK.md | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 63 insertions(+) create mode 100644 RTK.md diff --git a/.DS_Store b/.DS_Store index e32069e7e3749796a83bee26757ef12dff27129f..335b7fedd2b964089b5f64f1526868eba1a351a8 100644 GIT binary patch delta 834 zcmZoEXepTB&zQC`U^hRb$z&b@saWgD3=9k`3@Hrx49N_|x%n^Sa-DxZQ^z97ReI5|JJ0H}w7A&y~lv%nK3rr9qhpBIzd+$8MB#yWeeY`D+l|B{lE z-%0Yod1}l*FE9WViA}bXYG4-PJURKGloAJLOd8k$K#qhE!d@g{vB}!fyiDQ-ldYs@ zGjn$aPQD>6$9nWg-4ch%iZY^;1!Q>OJS8SxgUPNkO|1L1(_dLkJ|iO!WqpvD&d4~q zLsrK5VK&gwtPCX#sSL$H5+yL4isiz6Ac29R0^uyMipkGq<$O2-K)z=N8j;ITkW!qS zla!yI!-x>dNk;?{d&H}5gbZ@W4mLroty+4lo=x@!OUK?U~{=#BjaRlg|K*b z-pDqfW)=oLhIEEZh7x4$H7mPk#K2+?E{||7HhJXOV^1~Md_W zCi^M#Ah_$9mYtt0s3OMtOV9JC#bg~7Nj5NR$7FAn=W&g3V27nJBm#pW5!qq0&49{b q4ui`h9EMFE*y6#qpHTavCx!pGrNH{D}5}CU;+Rb@Akg{ delta 820 zcmZoEXepTB&zQO~U^hRb@njwWsaROp16XT=F=fxy9HwpW(v3`76nlCl^zog{k zcal7Co*MJ_3k*O-Vw3Hp8kqUcsZKs9rNmLyH}T#gpaXy$2_b~NNWx;1wWWEPgbOBH zNzZ2HGJG@nhO`{(x<5@KY?BpbL?;W#@W6RWOxzbHyUH}Ne!3*4&pG*wj69U}L1sE5 z!{iQG8D}A8prctCN*GcZih(3bU^w5@&5_#y4h$3(2xoy+OnxpaXUQG_@;x)qh+Kw( zoODEpux|2gM93hAb==9?sDIlh2g*sXL7Dk-63nbW9X5B#H8M_Y5T4Af5Ejp-U-Aa1 zpM^n>A)O(Up#<54e-RHVp$r3gJaTNYRW8_kKp}^T?bQrN)@9o#Cn(EI_EY9T zaMv>}FP|)^BF35;>?zDSSw}^Zja^7w7^u`+<$2uOe_)5DFeC!Korvr( `rtk git` +- `find` -> `rtk find` +- `grep` -> `rtk grep` +- `cat`, `head`, `tail` -> `rtk read` +- `ls` -> `rtk ls` +- `tree` -> `rtk tree` +- `pytest` -> `rtk pytest` +- `npm` -> `rtk npm` +- `npx` -> `rtk npx` +- `pnpm` -> `rtk pnpm` +- `cargo` -> `rtk cargo` +- `docker` -> `rtk docker` +- `kubectl` -> `rtk kubectl` +- `go` -> `rtk go` +- `ruff` -> `rtk ruff` +- `mypy` -> `rtk mypy` +- `tsc` -> `rtk tsc` +- `eslint`, `lint` -> `rtk lint` +- `playwright` -> `rtk playwright` +- `curl` -> `rtk curl` +- `wc` -> `rtk wc` + +## Examples + +```bash +rtk git status +rtk find . -name '*.ts' +rtk grep "TODO" src +rtk read package.json +rtk pytest -q +rtk npm run build +``` + +## Exceptions + +Use `rtk proxy ` when you need the raw command behavior but still want RTK tracking. + +## Verification + +```bash +rtk --version +rtk gain +which rtk +``` From 0f37e9c6850f328ea34bf107819af92299c2da8a Mon Sep 17 00:00:00 2001 From: caspersimon <165684406+caspersimon@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:27:06 +0100 Subject: [PATCH 2/6] Complete vision-first exam curation and review pipeline --- .DS_Store | Bin 14340 -> 14340 bytes Makefile | 2 +- data/vision_exam_pipeline/README.md | 35 + .../analytics/round1.json | 350 + data/vision_exam_pipeline/analytics/round1.md | 21 + .../evaluations/round1.json | 15332 ++++++++++++++++ .../exam_question_bank.json | 5277 ++++++ .../exam_question_bank_completeness.json | 85 + data/vision_exam_pipeline/page_manifest.json | 224 + .../plan_after_manual_synthesis.md | 283 + .../review_drops/README.md | 50 + ...on-programming-62oop21-manual-q06-q11.json | 161 + ...ing-62oop21-q01-q05-legacy-reverified.json | 131 + ...or-python-programming-62oop21-q12-q15.json | 105 + ...or-python-programming-62oop21-q16-q19.json | 106 + ...or-python-programming-62oop21-q20-q22.json | 80 + ...or-python-programming-62oop21-q23-q24.json | 55 + ...basics-2023-q01-q06-legacy-reverified.json | 156 + ...uide-trial-python-basics-2023-q07-q12.json | 156 + ...uide-trial-python-basics-2023-q13-q18.json | 157 + ...uide-trial-python-basics-2023-q19-q21.json | 81 + ...uide-trial-python-basics-2023-q22-q24.json | 82 + ...utions-py22-q01-q07-legacy-reverified.json | 187 + ...ial-final-exam-solutions-py22-q08-q15.json | 214 + ...ial-final-exam-solutions-py22-q16-q24.json | 230 + ...y-july-2023-q01-q03-legacy-reverified.json | 81 + ...y-july-2023-q04-q06-legacy-reverified.json | 80 + ...o-python-6013b0470y-july-2023-q07-q12.json | 155 + ...o-python-6013b0470y-july-2023-q13-q15.json | 80 + ...o-python-6013b0470y-july-2023-q16-q18.json | 81 + ...o-python-6013b0470y-july-2023-q19-q24.json | 158 + ...on-35761538-q01-q04-legacy-reverified.json | 109 + ...on-35761538-q05-q07-legacy-reverified.json | 80 + ...troduction-to-python-35761538-q08-q12.json | 130 + ...troduction-to-python-35761538-q13-q18.json | 156 + ...troduction-to-python-35761538-q19-q24.json | 159 + ...lus-answers-q01-q08-legacy-reverified.json | 207 + ...lus-answers-q09-q16-legacy-reverified.json | 205 + ...lus-answers-q17-q24-legacy-reverified.json | 206 + ...hon-3077951-q01-q03-legacy-reverified.json | 81 + ...hon-3077951-q04-q06-legacy-reverified.json | 83 + ...ntroduction-to-python-3077951-q07-q12.json | 156 + ...ntroduction-to-python-3077951-q13-q18.json | 155 + ...ntroduction-to-python-3077951-q19-q24.json | 155 + .../review_packets/round1.json | 900 + .../review_packets/round1.md | 175 + .../review_packets/round1_manual_synthesis.md | 424 + .../selectable_items_snapshot.json | 8990 +++++++++ .../synthesis/round1.json | 3000 +++ ...utions-for-python-programming-62oop21.json | 2142 +++ ...-study-guide-trial-python-basics-2023.json | 2125 +++ ...ython-trial-final-exam-solutions-py22.json | 2191 +++ ...-intro-to-python-6013b0470y-july-2023.json | 2102 +++ ...s-for-introduction-to-python-35761538.json | 2125 +++ .../round1/sample-final-plus-answers.json | 2724 +++ ...utions-introduction-to-python-3077951.json | 1998 ++ ...utions-for-python-programming-62oop21.json | 174 + ...-study-guide-trial-python-basics-2023.json | 170 + .../work_packets/extractions/index.json | 57 + ...ython-trial-final-exam-solutions-py22.json | 164 + ...-intro-to-python-6013b0470y-july-2023.json | 170 + ...s-for-introduction-to-python-35761538.json | 164 + .../sample-final-plus-answers.json | 74 + ...utions-introduction-to-python-3077951.json | 166 + docs/TESTING.md | 49 + docs/data/DATASET_INFO.md | 41 + ...009-vision-first-exam-curation-pipeline.md | 72 + pipelines/vision_exam_pipeline.py | 83 + pipelines/vision_exam_pipeline_bank.py | 466 + pipelines/vision_exam_pipeline_gemini.py | 450 + pipelines/vision_exam_pipeline_packet.py | 360 + pipelines/vision_exam_pipeline_review.py | 498 + pipelines/vision_exam_pipeline_shared.py | 187 + scripts/vision_exam_pipeline.py | 223 + tests/test_vision_exam_pipeline.py | 465 + 75 files changed, 59005 insertions(+), 1 deletion(-) create mode 100644 data/vision_exam_pipeline/README.md create mode 100644 data/vision_exam_pipeline/analytics/round1.json create mode 100644 data/vision_exam_pipeline/analytics/round1.md create mode 100644 data/vision_exam_pipeline/evaluations/round1.json create mode 100644 data/vision_exam_pipeline/exam_question_bank.json create mode 100644 data/vision_exam_pipeline/exam_question_bank_completeness.json create mode 100644 data/vision_exam_pipeline/page_manifest.json create mode 100644 data/vision_exam_pipeline/plan_after_manual_synthesis.md create mode 100644 data/vision_exam_pipeline/review_drops/README.md create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q23-q24.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json create mode 100644 data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q22-q24.json create mode 100644 data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json create mode 100644 data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json create mode 100644 data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json create mode 100644 data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json create mode 100644 data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json create mode 100644 data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json create mode 100644 data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json create mode 100644 data/vision_exam_pipeline/review_packets/round1.json create mode 100644 data/vision_exam_pipeline/review_packets/round1.md create mode 100644 data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md create mode 100644 data/vision_exam_pipeline/selectable_items_snapshot.json create mode 100644 data/vision_exam_pipeline/synthesis/round1.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-solutions-for-python-programming-62oop21.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-study-guide-trial-python-basics-2023.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round1/introduction-to-python-trial-final-exam-solutions-py22.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round1/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round1/resit-solutions-for-introduction-to-python-35761538.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round1/sample-final-plus-answers.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round1/trial-final-exam-solutions-introduction-to-python-3077951.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/final-exam-solutions-for-python-programming-62oop21.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/final-exam-study-guide-trial-python-basics-2023.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/index.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/introduction-to-python-trial-final-exam-solutions-py22.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/resit-solutions-for-introduction-to-python-35761538.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/sample-final-plus-answers.json create mode 100644 data/vision_exam_pipeline/work_packets/extractions/trial-final-exam-solutions-introduction-to-python-3077951.json create mode 100644 docs/specs/RM-009-vision-first-exam-curation-pipeline.md create mode 100644 pipelines/vision_exam_pipeline.py create mode 100644 pipelines/vision_exam_pipeline_bank.py create mode 100644 pipelines/vision_exam_pipeline_gemini.py create mode 100644 pipelines/vision_exam_pipeline_packet.py create mode 100644 pipelines/vision_exam_pipeline_review.py create mode 100644 pipelines/vision_exam_pipeline_shared.py create mode 100644 scripts/vision_exam_pipeline.py create mode 100644 tests/test_vision_exam_pipeline.py diff --git a/.DS_Store b/.DS_Store index 335b7fedd2b964089b5f64f1526868eba1a351a8..daa4ad802150db6f221723fccabd955fb7c321de 100644 GIT binary patch delta 171 zcmWO0u@1pd6adhBUthG1ik65*krzS?2vM8Auu7URScrR%WF>XM zx*-jmaL*132y|)O5ZG(}Fgew6$d-B_JzG^yTStM&Zs%okS)d?&RL(&Rpe%OeSEHgo WFflv4Ge9%TqlKT+xfF1}dl!F2YbuKX delta 374 zcmZoEXepQ=#l*xpQN~y_je&uInSnuofgzcpI5WAdASow5Y2(GkjFSyaSSEH0Zsynf z!MO3kXXef994s7+CKD&fY~~S&=VfG^oFhAlk#X~X*$<42hMRd5Rx#G|Gw3lCFyt^K zGE_2@GZZmoGNdzPFqAOp0u9e$$jnJM3{K9^EdW}{z`ztd2}lyqk(=-00&);gCC3Ai z8{N~kA9uv9%NJ%*Zhi_0+F-g0GLW6uFqvCPdh=PuDkesT%^oWII5%E3WSq=yAk4.json`: per-question snippet evaluations +- `synthesis/.json`: grouped edit/addition suggestions for human review +- `analytics/.json` and `analytics/.md`: ranking-prep summaries +- `work_packets/extractions/*.json`: per-exam capture packets +- `work_packets/evaluations//*.json`: per-exam evaluation packets + +Workflow: + +```bash +python3 scripts/vision_exam_pipeline.py prepare-pages +python3 scripts/vision_exam_pipeline.py seed-question-bank +python3 scripts/vision_exam_pipeline.py audit-completeness +python3 scripts/vision_exam_pipeline.py dispatch-extraction +python3 scripts/vision_exam_pipeline.py dispatch-evaluations --round round1 --findings tmp/exam_coverage_audit/seed_exact_matches.json +python3 scripts/vision_exam_pipeline.py synthesize-suggestions --round round1 +python3 scripts/vision_exam_pipeline.py generate-ranking-analytics --round round1 +python3 scripts/vision_exam_pipeline.py generate-review-packet --round round1 +python3 scripts/vision_exam_pipeline.py validate --evaluation-round round1 +``` + +Policy: + +- Use rendered PNG pages as the review source of truth. +- Do not use `pdftotext`, OCR, or other deterministic text extraction for exam question capture in this workflow. +- Keep human review between evaluation/synthesis and any later snippet-content implementation round. diff --git a/data/vision_exam_pipeline/analytics/round1.json b/data/vision_exam_pipeline/analytics/round1.json new file mode 100644 index 0000000..4b98c8b --- /dev/null +++ b/data/vision_exam_pipeline/analytics/round1.json @@ -0,0 +1,350 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:43Z", + "round": "round1", + "input_evaluations_path": "data/vision_exam_pipeline/evaluations/round1.json", + "summary": { + "total_evaluations": 168, + "completed_evaluations": 168, + "status_counts": { + "completed": 168 + }, + "answerability_counts": { + "certain": 88, + "partial": 40, + "insufficient": 40 + } + }, + "weeks": [ + { + "week": 1, + "top1_unique_snippets": 8, + "top3_unique_snippets": 18, + "minimal_set_unique_snippets": 15, + "minimal_set_unused_snippets": 57, + "unused_snippet_ids": [ + "cs-09e2b215ee", + "cs-23b2cfd4d6", + "cs-266616a010", + "cs-3cb4b8e8f9", + "cs-4155022ebf", + "cs-4f8a5f420b", + "cs-5b89a10dcd", + "cs-6d0d650063", + "cs-7eb8617d28", + "cs-814a07a136", + "cs-beb6591b24", + "cs-c25503e5db", + "cs-curated-hw-seq-nth-occurrence", + "cs-curated-hw-seq-slice-between-sentinels", + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "exam-extra_practice-11-w1-objects-and-names", + "exam-midterm_2023-12-w1-functions-and-imports", + "exam-midterm_2023-4-w1-objects-and-names", + "exam-midterm_2024-16-w1-functions-and-imports", + "exam-midterm_2024-4-w1-objects-and-names", + "exam-midterm_2024-6-w1-objects-and-names", + "exam-trial_midterm-11-w1-objects-and-names", + "exam-trial_midterm-12-w1-objects-and-names", + "exam-trial_midterm-14-w1-objects-and-names", + "exam-trial_midterm-16-w1-objects-and-names", + "exam-trial_midterm-18-w1-objects-and-names", + "exam-trial_midterm-20-w1-objects-and-names", + "exam-trial_midterm-21-w1-objects-and-names", + "exam-trial_midterm-22-w1-objects-and-names", + "exam-trial_midterm-24-w1-objects-and-names", + "exam-trial_midterm-7-w1-objects-and-names", + "exam-trial_midterm-9-w1-objects-and-names", + "kp-6-d2", + "kp-9", + "kp-manual-aliasing-copy", + "kp-manual-aliasing-copy-d1", + "ks-0153de2f70", + "ks-03c874b8bb", + "ks-419e787b39", + "ks-61c5deec4a", + "ks-685cd3d828", + "ks-6f41148083", + "ks-95be7f9418", + "ks-be78ccac04", + "ks-c0135e2a4a", + "ks-c815ffe1d5", + "ks-cb3a9e3fd2", + "ks-d79a1899f6", + "ks-df3b849d59", + "ks-e88d0a8060" + ] + }, + { + "week": 2, + "top1_unique_snippets": 22, + "top3_unique_snippets": 34, + "minimal_set_unique_snippets": 31, + "minimal_set_unused_snippets": 62, + "unused_snippet_ids": [ + "cs-3e39a2f12f", + "cs-curated-hw-conditions-first-match-wins", + "cs-curated-hw-dict-delete-shared-keys", + "cs-curated-hw-dict-digit-frequency", + "cs-curated-hw-dict-project-values-sorted-keys", + "cs-curated-hw-loops-enumerate-mark-max", + "cs-curated-hw-loops-market-clearing", + "cs-curated-hw-loops-nested-pairwise-dict", + "cs-curated-hw-loops-zip-filter-pairs", + "cs-fc8bdeb969", + "exam-Resit 22/23-1-w2-lists-and-sets", + "exam-extra_practice-12-w2-dictionaries-and-mappings", + "exam-extra_practice-3-w2-dictionaries-and-mappings", + "exam-extra_practice-8-w2-dictionaries-and-mappings", + "exam-midterm_2023-1-w2-conditions", + "exam-midterm_2023-15-w2-lists-and-sets", + "exam-midterm_2023-2-w2-loops", + "exam-midterm_2023-5-w2-dictionaries-and-mappings", + "exam-midterm_2023-6-w2-dictionaries-and-mappings", + "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "exam-midterm_2024-10-w2-dictionaries-and-mappings", + "exam-midterm_2024-11-w2-dictionaries-and-mappings", + "exam-midterm_2024-12-w2-dictionaries-and-mappings", + "exam-midterm_2024-17-w2-loops", + "exam-midterm_2024-20-w2-loops", + "exam-midterm_2024-21-w2-loops", + "exam-midterm_2024-22-w2-lists-and-sets", + "exam-midterm_2024-23-w2-lists-and-sets", + "exam-midterm_2024-24-w2-lists-and-sets", + "exam-midterm_2024-3-w2-loops", + "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "exam-midterm_2024-8-w2-dictionaries-and-mappings", + "exam-midterm_2024-9-w2-loops", + "exam-trial_midterm-13-w2-conditions", + "exam-trial_midterm-2-w2-dictionaries-and-mappings", + "exam-trial_midterm-23-w2-dictionaries-and-mappings", + "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "kp-1-d3", + "kp-manual-break-continue", + "kp-manual-enumerate", + "kp-manual-loop-core", + "kp-manual-precedence", + "kp-manual-ternary", + "kp-manual-while-truthy", + "ks-08ac820c2f", + "ks-4258f15a6c", + "ks-4b427a2425", + "ks-4c6274845e", + "ks-59aaf6b0ee", + "ks-624034d573" + ] + }, + { + "week": 3, + "top1_unique_snippets": 22, + "top3_unique_snippets": 34, + "minimal_set_unique_snippets": 26, + "minimal_set_unused_snippets": 38, + "unused_snippet_ids": [ + "aiq-7", + "cs-curated-hw-hof-nested-helper-hhi", + "exam-extra_practice-2-w3-scope", + "exam-extra_practice-7-w3-return-behavior", + "exam-midterm_2023-11-w3-higher-order-patterns", + "exam-midterm_2023-13-w3-higher-order-patterns", + "exam-midterm_2023-3-w3-scope", + "exam-midterm_2024-1-w3-return-behavior", + "exam-midterm_2024-13-w3-arguments", + "exam-midterm_2024-14-w3-arguments", + "exam-midterm_2024-19-w3-higher-order-patterns", + "exam-midterm_2024-5-w3-scope", + "exam-trial_midterm-17-w3-higher-order-patterns", + "kp-2-d2", + "kp-3-d2", + "kp-manual-scope-global", + "kp-manual-scope-local", + "kp-manual-scope-unbound", + "ks-00b2983ca8", + "ks-14515a5856", + "ks-40fee04740", + "ks-994a4083e3", + "ks-ab66f3bab6", + "ks-d1a2d7739d", + "ks-d26b85265c", + "ks-db93da9e3e", + "ks-e09d7f145b", + "ks-f5d65c7e89", + "manual-call-vs-index", + "manual-global", + "manual-list-of-dicts-loop", + "manual-local-name", + "manual-scope-global-change", + "manual-scope-local-name", + "manual-scope-rebind-parameter", + "manual-scope-unbound", + "manual-string-return-shape", + "manual-unboundlocal" + ] + }, + { + "week": 4, + "top1_unique_snippets": 7, + "top3_unique_snippets": 13, + "minimal_set_unique_snippets": 11, + "minimal_set_unused_snippets": 37, + "unused_snippet_ids": [ + "aiq-6", + "cs-0d319e4faf", + "cs-14245b8c1f", + "cs-30e53467b8", + "cs-e7bc165499", + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "kp-manual-init-defaults", + "kp-manual-init-defaults-d1", + "kp-manual-string-method-results", + "kp-manual-string-method-results-d1", + "ks-2c73fabc68", + "ks-309158a68c", + "ks-40d373c410", + "ks-45aead894c", + "ks-5198d93ec1", + "ks-5cbba26b09", + "ks-72dda5450c", + "ks-acb7f400b2", + "ks-b734a22f46", + "ks-bdea67862f", + "ks-cdb152720e", + "ks-e4dc502d3e", + "ks-ea5a4acb43", + "ks-f80f1bf556", + "manual-find-vs-index", + "manual-method-call", + "manual-oop-attrs", + "manual-oop-constructor-defaults", + "manual-self", + "manual-string-escapes", + "manual-string-format-method", + "manual-string-immutability", + "manual-string-islower-method", + "manual-string-literals-example", + "manual-string-repetition" + ] + }, + { + "week": 5, + "top1_unique_snippets": 8, + "top3_unique_snippets": 9, + "minimal_set_unique_snippets": 9, + "minimal_set_unused_snippets": 47, + "unused_snippet_ids": [ + "cs-2e178eda82", + "cs-3d987070d4", + "cs-49cf15967e", + "cs-82ef14b9d5", + "cs-8bae99d6de", + "cs-8ec741987c", + "cs-b069af91f4", + "cs-b3e0b57d7a", + "cs-c4c296595e", + "cs-cdfd529b3d", + "cs-e6b6bd65f0", + "kp-1-d2", + "kp-manual-df-constructor", + "kp-manual-drop-missing", + "kp-manual-drop-missing-d1", + "kp-manual-drop-missing-d2", + "kp-manual-series-default-index", + "kp-manual-series-vs-df", + "ks-0114a2cff0", + "ks-052ed25923", + "ks-0d2d15f8d2", + "ks-115ab52188", + "ks-17e621a20d", + "ks-18a9645168", + "ks-21496ff1cd", + "ks-2bed6c308f", + "ks-305a41a33e", + "ks-57ff66f9f1", + "ks-591dd1aa33", + "ks-75cf35c8b4", + "ks-99fe849762", + "ks-9a5d2c05fb", + "ks-dfc064979d", + "ks-f1be187b50", + "ks-f550a3ffc7", + "ks-f8eec928e1", + "manual-df-constructor", + "manual-pandas-df", + "manual-pandas-import", + "manual-pandas-map-column-sum", + "manual-pandas-select-shape", + "manual-pandas-series", + "manual-pandas-split-into-columns", + "manual-series-index", + "manual-series-vs-dataframe", + "manual-working-values-axis-apply", + "manual-working-values-string-vs-map" + ] + }, + { + "week": 6, + "top1_unique_snippets": 8, + "top3_unique_snippets": 13, + "minimal_set_unique_snippets": 14, + "minimal_set_unused_snippets": 50, + "unused_snippet_ids": [ + "ai-example-1", + "ai-example-2", + "ai-example-3", + "ai-example-4", + "ai-example-5", + "ai-example-6", + "ai-example-7", + "ai-example-8", + "cs-905c77e1f3", + "kp-1", + "kp-1-d1", + "kp-2-d1", + "kp-3", + "kp-3-d1", + "kp-4-d1", + "kp-5", + "kp-5-d1", + "kp-6", + "kp-6-d1", + "kp-7", + "kp-7-d1", + "kp-8", + "kp-8-d1", + "kp-manual-datetime-day-of-year", + "kp-manual-datetime-delta", + "kp-manual-datetime-format", + "kp-manual-datetime-iso", + "kp-manual-datetime-now", + "kp-manual-datetime-replace", + "ks-0a4fcae36d", + "ks-0e5c8b8b42", + "ks-169cc25be1", + "ks-1bc815f6d1", + "ks-3e04c4d5e8", + "ks-662456da41", + "ks-72c58bb6b2", + "ks-900b394f8e", + "ks-b9d93f2bc1", + "ks-cacc4fbc21", + "ks-cd030b9520", + "ks-dd2965ef50", + "ks-e643ee5e77", + "manual-datetime-delta", + "manual-datetime-iso", + "manual-datetime-overlap", + "manual-datetime-replace", + "manual-datetime-strftime-loop", + "manual-day-of-year", + "manual-strftime-vs-strptime", + "manual-timedelta-attrs" + ] + } + ], + "insights": [ + "Week 2 currently has the broadest minimal-set footprint with 31 unique snippets." + ], + "comparison": {} +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/analytics/round1.md b/data/vision_exam_pipeline/analytics/round1.md new file mode 100644 index 0000000..4aebc1e --- /dev/null +++ b/data/vision_exam_pipeline/analytics/round1.md @@ -0,0 +1,21 @@ +# Ranking Analytics (round1) + +- Total evaluations: `168` +- Completed evaluations: `168` +- Status counts: `{"completed": 168}` +- Answerability counts: `{"certain": 88, "insufficient": 40, "partial": 40}` + +## Week Summary + +| Week | Top 1 unique | Top 3 unique | Minimal-set unique | Minimal-set unused | +|---|---:|---:|---:|---:| +| 1 | 8 | 18 | 15 | 57 | +| 2 | 22 | 34 | 31 | 62 | +| 3 | 22 | 34 | 26 | 38 | +| 4 | 7 | 13 | 11 | 37 | +| 5 | 8 | 9 | 9 | 47 | +| 6 | 8 | 13 | 14 | 50 | + +## Insights + +- Week 2 currently has the broadest minimal-set footprint with 31 unique snippets. diff --git a/data/vision_exam_pipeline/evaluations/round1.json b/data/vision_exam_pipeline/evaluations/round1.json new file mode 100644 index 0000000..b794620 --- /dev/null +++ b/data/vision_exam_pipeline/evaluations/round1.json @@ -0,0 +1,15332 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "question_bank_path": "data/vision_exam_pipeline/exam_question_bank.json", + "selectable_items_path": "data/vision_exam_pipeline/selectable_items_snapshot.json", + "questions": [ + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q01", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q01", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "Take a look at the following class definition.\n\nclass Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nGiven the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\nWhy?", + "options": { + "a": "The first argument (my_flight) should not have been passed to the set_date method in Code line 2.", + "b": "The capacity of the flight is not specified as an argument in Code line 1.", + "c": "The argument self is missing in Code line 1.", + "d": "The date string passed as an argument in Code line 2 represents an invalid date." + }, + "correct": "a", + "explanation": "set_date is an instance method, so Python passes self automatically. Passing my_flight explicitly adds an extra argument and causes the error.", + "code_context": "class Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\")\nmy_flight.set_date(my_flight, \"29-02-2022\")" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Given the class definition above, trying to execute the following two code lines will result in a Python error. my_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1 my_fli", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "kp-4", + "rationale": "This snippet explicitly describes the exact error pattern in the question (obj.set_date(obj, x)) and explains that it passes 'one argument too many' because self is passed automatically." + }, + "top_three_snippets": [ + { + "item_id": "kp-4", + "rationale": "Directly explains the mechanical error of passing the instance explicitly in a method call." + }, + { + "item_id": "manual-method-call", + "rationale": "Provides a clear conceptual explanation of why Python adds the instance automatically and how manual inclusion results in an argument count error." + }, + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Matches the exact code and scenario from the exam question, providing a direct reference for the student." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "kp-4", + "rationale": "Provides the rule and the specific error syntax." + }, + { + "item_id": "ks-9e278d1ee6", + "rationale": "Explains what 'self' is, which helps a novice understand why the parameter exists in the definition but is omitted in the call." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet kp-4 and manual-method-call explicitly address the 'extra argument' error caused by passing the object instance manually, which is the core concept of the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage for this specific concept (automatic self-passing vs manual passing errors) is excellent.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:41:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q02", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q02", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "You have the following definition for a Book class.\n\nclass Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)\n\nSuppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book. The compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?", + "options": { + "a": "def compare(self, other):\n avg_better = self.average_score() > other.average_score()\n no_fewer_reviews = self.num_reviews() >= other.num_reviews()\n if avg_better and no_fewer_reviews:\n return self.title\n elif not avg_better:\n return other.title\n else:\n return None", + "b": "def compare(self, other):\n for first, second in [(self, other), (other, self)]:\n avg_better = first.average_score() > second.average_score()\n no_fewer_reviews = first.num_reviews() >= second.num_reviews()\n if avg_better and no_fewer_reviews:\n return first.title\n return None", + "c": "Both methods above compare the book objects as intended.", + "d": "Neither of the two methods above compare the book objects as intended." + }, + "correct": "b", + "explanation": "B checks whether either book is better than the other and returns that title, otherwise it returns None. A can incorrectly return the other book even when neither book is better.", + "code_context": "class Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another b", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet contains the exact logic requirements for the 'better than' comparison (average score higher AND at least as many reviews), which is the core of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Defines the specific business logic/rules the student must implement." + }, + { + "item_id": "manual-oop-state-compare", + "rationale": "Provides a nearly identical class structure (Book, add_review, average) allowing a student to understand how methods are called on instances." + }, + { + "item_id": "manual-oop-init-defaults", + "rationale": "Helps a student understand attribute initialization (self.title, self.review_scores), which is necessary to understand what the options are returning." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Logic rules." + }, + { + "item_id": "manual-oop-state-compare", + "rationale": "Structural context." + }, + { + "item_id": "manual-oop-init-defaults", + "rationale": "Attribute context." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain the rules and the class structure, but they don't explicitly teach the 'symmetric comparison' pattern used in Option B. A student might struggle to realize that Option A is logically flawed (it assumes if self isn't better, the other must be) without a snippet explaining mutual exclusion in complex conditions.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets provide the 'what' (rules) and the 'where' (class), but miss the 'why' regarding the logical structure of comparison functions.", + "missing_concepts": [ + "Symmetric comparison logic", + "Handling 'None' as a fallback when multiple conditions aren't met", + "Logical fallacies in multi-attribute comparison" + ], + "proposed_fix": "Add an AI example snippet showing a comparison method between two objects that returns None if neither meets a strict 'better' criteria." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: 'Comparing Objects with Multiple Criteria'. Snippet: 'When comparing two objects (A, B) based on multiple rules, remember that ! (A > B) does not imply (B > A). Example: def compare(self, other): if self.val > other.val and self.count >= other.count: return self; if other.val > self.val and other.count >= self.count: return other; return None'", + "why_helpful": "This directly addresses the logical pitfall in Option A and explains the necessity of the structure in Option B.", + "why_maybe_unnecessary": "Some students might infer the logic if they are strong in general boolean reasoning.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:41:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q03", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q03", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?", + "options": { + "a": "def get_tld(url):\n url_1 = url.split(\".\")[-1]\n return url_1.split(\"/\")[0]", + "b": "def get_tld(url):\n url_1 = url.split(\"//\")[1]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]", + "c": "def get_tld(url):\n return url.split(\"//\")[1].split(\"/\")[0].split(\".\")[-1]", + "d": "def get_tld(url):\n url_1 = url[url.find(\"www\") + 2:]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]" + }, + "correct": "a", + "explanation": "A splits on the last dot first, which leaves the page extension rather than the domain. The other options isolate the host name first and then extract the final dot-separated part.", + "code_context": "def get_tld(url):\n # Extract the top-level domain from a URL string" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following form", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the exact same question as the one being asked. It provides the problem statement, format, and logic required to solve the task." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Direct match for the question; provides the exact context and structure of the expected answer." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "While the topic says 'Conditions', the content is about string methods and 'does NOT achieve' logic, which mirrors the question's structure." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Another string-processing function question that helps a student understand how functions manipulate string inputs to produce specific outputs." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Since this is the exact question, it is technically sufficient for a student to find the answer by pattern matching." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the candidate list. A student can simply match the 'get_tld' function name and the URL format to the snippet to find the answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact answer is present, there is a conceptual gap in explaining how the '.split()' method, negative indexing ([-1]), and 'find()' actually work.", + "missing_concepts": [ + ".split() method behavior", + "Negative indexing in strings/lists ([-1])", + "String slicing with [start:]", + ".find() method return values" + ], + "proposed_fix": "Add a conceptual snippet or 'cheat sheet' card explaining string slicing and the split method, as these are the primary tools used in all options (a, b, c, d)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'String Manipulation Reference' card that explicitly shows: 1) 'text.split(\".\")' returns a list, 2) 'list[-1]' gets the last item, 3) 'text.find(\"x\")' returns an integer index.", + "why_helpful": "It allows a student with zero knowledge to logically evaluate why option 'a' fails (it splits on dots first, making the extension the last item) vs why 'b' and 'c' succeed (they isolate the host first).", + "why_maybe_unnecessary": "The student can technically 'solve' the exam by just finding the exact match snippet provided.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:42:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q04", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q04", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "def is_anagram(word_1, word_2):\n return sorted(list(word_1.replace(\" \", \"\").lower())) == sorted(list(word_2.replace(\" \", \"\").lower()))", + "b": "def is_anagram(word_1, word_2):\n return word_1.replace(\" \", \"\").lower().sort() == word_2.replace(\" \", \"\").lower().sort()", + "c": "def is_anagram(word_1, word_2):\n return list(word_1.replace(\" \", \"\").lower()).sort() == list(word_2.replace(\" \", \"\").lower())", + "d": "def is_anagram(word_1, word_2):\n return sorted(list(word_1)).replace(\" \", \"\").lower() == sorted(list(word_2)).replace(\" \", \"\").lower()" + }, + "correct": "a", + "explanation": "A removes spaces, lowercases both strings, and compares the sorted letters. The other options misuse sort() or apply string operations to list objects in the wrong order.", + "code_context": "def is_anagram(word_1, word_2):\n # Compare the same letters in normalized, sorted form" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be writt", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-4-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 4, + "question_summary": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be writt", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-4-w2-conditions", + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This snippet is the exact same question from a previous exam. It provides the full code for is_anagram, identifies the correct answer (a), and explains that .sort() misuses return values while sorted() is correct for comparisons." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Identical previous exam question providing the exact logic and explanation needed." + }, + { + "item_id": "aiq-4", + "rationale": "Provides a critical conceptual warning to check if methods mutate in place, which is the primary 'trap' in options B and C (using .sort())." + }, + { + "item_id": "aiq-2", + "rationale": "Reinforces the concept of in-place mutation vs. return values for list operations, helping a student distinguish between .sort() and sorted()." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Directly answers the question with zero inference required." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the identical question from a past exam, which contains the correct implementation and a clear explanation of why the alternatives are wrong.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The exact answer is present, but the student relies on finding that specific match. General rules about method chaining and type-specific errors (like calling .replace() on a list) are not explicitly summarized.", + "missing_concepts": [ + "Explicit rule that .sort() returns None (causing comparisons to fail).", + "Explicit rule that string methods (.replace, .lower) cannot be called on list objects returned by sorted()." + ], + "proposed_fix": "Add a summary card focused on 'Method Chaining & Return Values' specifically comparing string methods vs. list methods." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Method Cheat Sheet' snippet: 1. Strings: .lower(), .replace(), .strip() return NEW strings. 2. Lists: .sort(), .append(), .reverse() return NONE (mutate in place). 3. Functions: sorted(x) returns a NEW sorted list, len(x) returns an int. 4. Warning: You cannot call .replace() on a list!", + "why_helpful": "This allows a student to solve the logic (Option D fails because it's a list; Option B/C fail because they return None) even if they don't find the exact duplicate question.", + "why_maybe_unnecessary": "The presence of the exact exam question in the database makes this redundant for this specific task.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:42:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q05", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q05", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "Pandas", + "question": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "s.map((s - s.mean())**2)", + "b": "(s - s.mean())**2", + "c": "s.map(lambda x: (x - s.mean())**2)", + "d": "(s - s.mean()).map(lambda x: x**2)" + }, + "correct": "a", + "explanation": "A is not the right way to apply the squared-difference expression to each element of the Series. B, C, and D all produce the desired squared differences.", + "code_context": "# s is a pandas Series of floats" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the correspondin", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "It explicitly explains that the .map() method is used to apply a function. This allows a student to deduce that passing a pre-calculated Series (Option A) is incorrect." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Clarifies that .map() expects a function, which is the core reason why Option A is the answer." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Explains that vectorized operations in Pandas are performed directly on columns/Series, validating Option B." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Provides an example of applying squaring functions to elements, helping the student understand the logic in Options C and D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Defines .map() as a tool for applying functions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Defines vectorized math for Pandas structures." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets explain what .map() and vectorized operations are, the student must still perform the logical step of identifying that a Series object is not a 'function' to eliminate Option A.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover the 'how' for the correct options but don't explicitly warn against the common mistake of passing a Series into .map().", + "missing_concepts": [ + "The distinction between passing a function vs. a Series/array to the .map() method." + ], + "proposed_fix": "Update the exact-match snippet to include its original explanation, which highlights that A is not the right way to apply expressions." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "proposal": "Expand search_text to include the explanation: 'Option A is incorrect because .map() expects a function (like a lambda) or a dictionary to map values, not a pre-computed Series of the same length.'", + "why_helpful": "It directly addresses the 'why' of the question, making the answer obvious to a student without prior knowledge.", + "why_maybe_unnecessary": "The student might be able to infer this from the generic .map() description in other snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:43:12Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q06", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q06", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-2", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the difference of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] - df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x - df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\"] - df.columns[\"B\"]", + "d": "df[\"C\"] = df.apply(df[\"A\"] - df[\"B\"])" + }, + "correct": "a", + "explanation": "Subtracting one numeric Series from another directly creates the elementwise difference needed for column C.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This snippet describes the exact same scenario (creating column C from columns A and B) using the 'sum' operation. A student can easily deduce that replacing '+' with '-' performs subtraction." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides the structural template for vectorized column creation (A + B) which directly maps to the question (A - B)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces the concept of vectorized operations in Pandas, explicitly mentioning 'Vectorized addition' in the search text." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Shows operations on Series involving subtraction ('difference between...'), which helps confirm the '-' operator's usage in a pandas context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "The structural similarity is so high that this single snippet is likely enough for a student to guess the correct syntax." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets provide the identical syntactical pattern (df['C'] = df['A'] + df['B']). Translating 'sum' to 'difference' by changing the operator is a natural logical step even for non-programmers.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover vectorized addition perfectly, but do not explicitly show vectorized subtraction.", + "missing_concepts": [ + "Explicit vectorized subtraction syntax" + ], + "proposed_fix": "Add a snippet or modify an existing one to show that subtraction (-) works the same way as addition (+) in Pandas column operations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating element-wise subtraction: df['diff'] = df['X'] - df['Y'].", + "why_helpful": "It removes the slight leap of faith required to assume '-' works exactly like '+'.", + "why_maybe_unnecessary": "The 'sum' example is already extremely suggestive of the correct answer.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:00:50Z" + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q07", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q07", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-3", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 8.7 4.6 9.5 7.0\n2 7.3 1.5 6.3 7.1\n3 4.3 9.0 2.9 3.3\n4 4.8 2.5 5.1 3.0\n5 1.6 1.4 6.7 3.5\n6 2.4 3.7 7.6 1.3\n\nSuppose that you'd like to create a new Series that only contains those elements of column \"D\" of df that are smaller than 5.0. So the Series should look like this, when printed:\n\n3 3.3\n4 3.0\n5 3.5\n6 1.3\nName: D, dtype: float64\n\nWhich of the following code lines will not achieve what you want?", + "options": { + "a": "df.loc[2:6, df.columns[-1]]", + "b": "df.loc[df[\"D\"] < 5, \"D\"]", + "c": "df.loc[3:6, \"D\"]", + "d": "df.iloc[2:6, 3]" + }, + "correct": "a", + "explanation": "Option A slices rows 2 through 6 from the last column but does not filter out values that are 5.0 or larger, so it includes values that should not be in the result.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is a parallel version of the same question from a different exam year, providing a direct example of DataFrame selection and filtering logic which helps the student identify the pattern." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Directly matches the question structure and topic of pandas DataFrame selection." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a boolean mask for index selection and explains 'loc' logic, which is essential for understanding option B." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides additional context on pandas Series operations and structure, reinforcing how pandas handles numeric data." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides the most direct structural comparison for the student." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Introduces the concept of boolean masks used in the filtering logic of the question." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets provide parallel examples, a student with zero Python knowledge would struggle to distinguish between .loc (inclusive of end label) and .iloc (exclusive of end position) without a snippet that explicitly defines those mechanics. They might guess based on the 'Trial' exam snippet, but the technical 'why' is missing.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a clear explanation of the difference between label-based (.loc) and integer-position-based (.iloc) indexing, specifically regarding the inclusivity of the stop index.", + "missing_concepts": [ + "Difference between .loc (label-based, inclusive) and .iloc (position-based, exclusive)", + "How integer-based labels in .loc behave similarly to/differently from slicing", + "Explicit definition of boolean indexing (e.g., df[df['D'] < 5])" + ], + "proposed_fix": "Add a summary or 'cheat-sheet' style snippet that explicitly contrasts .loc, .iloc, and boolean masks with examples." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a conceptual snippet titled 'Pandas Selection Rules' that explains: 1. .loc[start:stop] is label-based and INCLUDES stop. 2. .iloc[start:stop] is zero-indexed position-based and EXCLUDES stop. 3. Boolean masks return only rows where the condition is True.", + "why_helpful": "This provides the 'rules of the game' that allow a student to logically deduce why Option A includes row 2 (label 2) while Option D starts at row 3 (position 2).", + "why_maybe_unnecessary": "If the student finds the full solution in the expanded 'Trial' exam snippet (item 6), they might just memorize the answer pattern.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:43:41Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q08", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q08", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-4", + "question": "You have two DataFrames: df1 and df2. They look like this when printed:\n\nprint(df1)\n\n Age Height Female City Language\n0 23 167 True Berlin German\n1 36 175 True Frankfurt German\n2 17 182 False Antwerpen Dutch\n3 25 177 True Eindhoven Dutch\n4 36 178 False Lyon French\n5 52 185 False Basel German\n6 46 168 True Innsbruck German\n\nprint(df2)\n\n Age Height Female City Language\n5 52 185 False Basel German\n4 36 178 False Lyon French\n1 36 175 True Frankfurt German\n6 46 168 True Innsbruck German\n0 23 167 True Berlin German\n\nWhich of the following code segments could have created df2 from df1?", + "options": { + "a": "df1.loc[df1[\"Language\"].isin([\"French\", \"German\"])].sort_values(\"Height\", ascending=False)", + "b": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_values(\"Age\", ascending=False)", + "c": "df1.loc[~df1[\"Language\"].isin([\"Dutch\"]), [\"Age\", \"Height\", \"City\", \"Language\"]].sort_index(ascending=False)", + "d": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_index(axis=1)" + }, + "correct": "a", + "explanation": "Option A filters out the Dutch rows and then sorts the remaining rows by Height in descending order, matching df2 exactly.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "It identifies the topic of 'Inspecting and Selecting Data' in Pandas, which is the core of the question, although the snippet content itself is truncated and does not provide the syntax rules." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Contextualizes Pandas selection tasks." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic Pandas DataFrame syntax (column creation/vectorization), which helps a student recognize the library structure." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Reinforces the concept of working with named columns in a DataFrame." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Closest match for the 'Selecting Data' theme." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the syntax for filtering (isin, !=, ~) or sorting (sort_values) in Pandas. A student with zero Python knowledge would not know what 'isin' does or how 'ascending=False' affects the result based on the provided candidates.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide zero explanation for Pandas-specific method syntax required to evaluate the options.", + "missing_concepts": [ + "pandas.DataFrame.sort_values(by, ascending)", + "pandas.Series.isin(list)", + "Boolean indexing/filtering with .loc", + "The negation operator (~) in Pandas boolean masks" + ], + "proposed_fix": "Add a summary snippet for Week 5 Pandas operations covering filtering (isin, comparisons) and sorting (sort_values)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas Filtering and Sorting. Content: Use df.loc[condition] to filter rows. Conditions: df['col'] == 'val', df['col'].isin(['a', 'b']), or ~ (not). Use df.sort_values('col', ascending=False) to sort by a column in descending order.", + "why_helpful": "It directly explains the functions used in the exam question options (isin, sort_values, ascending).", + "why_maybe_unnecessary": "If this information is expected to be in a lecture-based summary snippet that was simply not included in this search batch.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:43:58Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q09", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q09", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-1", + "question": "You have a list of mountain peaks and their heights in meters, all formatted as \"[PEAK NAME]: [HEIGHT]m\". For example, a few elements of the list are:\n\"Denali: 6,190m\", \"Aconcagua: 6,961m\", \"Kilimanjaro: 5,895m\", ...\n\nAs you can see, the comma (\",\") is used as a thousand separator in the height. The list is called mountains.\n\nYou'd like to create a dictionary called peaks from the mountains list. The peak names would be the keys, and the corresponding integer values. Continuing the example above, a few key-value pairs of the peaks dictionary should be:\n\"Denali\": 6190, \"Aconcagua\": 6961, \"Kilimanjaro\": 5895, ...\n\nWhich of the following two code segments achieves what you want?", + "options": { + "a": "peaks = {peak.split(\":\")[0]: int(peak.split(\": \")[1][:-1].replace(\",\", \"\")) for peak in mountains}", + "b": "names = [peak.split(\":\")[0] for peak in mountains]\nheights = [int(peak.split(\": \")[1].replace(\",\", \"\").replace(\"m\", \"\")) for peak in mountains]\npeaks = dict(zip(names, heights))", + "c": "Both code segments above achieve the intended outcome.", + "d": "Neither of the two code segments above achieves the intended outcome." + }, + "correct": "c", + "explanation": "Both solutions strip off the trailing m, remove the thousands separator, convert the height to an integer, and pair each mountain name with its numeric height.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Directly addresses creating a dictionary (word_lengths) from a list of strings (words), which is the primary task of the exam question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Covers the pattern of mapping a list to a dictionary with transformed keys/values." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Relevant to Option B as it involves creating a dictionary from two separate lists (names and ages)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Demonstrates string manipulation (splitting, replacing characters) which is crucial for cleaning the height data in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Establishes the dictionary-from-list pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides context for multi-list dictionary creation (zip-like behavior)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Shows string cleaning methods (replace)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Shows complex string extraction (top-level domain from URL), similar to extracting peak names and heights." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While existing snippets cover dictionary creation from lists and string manipulation separately, none explicitly show the 'dictionary comprehension' syntax {k: v for ...} or the 'dict(zip(...))' pattern in a single clear example that a novice could map 1:1 to the options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a clear example of dictionary comprehension syntax and the specific use of slicing [:-1] to remove a trailing character in a list context.", + "missing_concepts": [ + "dictionary comprehension syntax", + "zip() function for pairing lists", + "string slicing [:-1] for removing suffix", + "int() conversion within comprehensions" + ], + "proposed_fix": "Add a new snippet or edit an existing one to explicitly show a dictionary comprehension that includes a transformation (like int() or a string method)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: my_dict = {item.split(':')[0]: int(item.split(':')[1]) for item in my_list}", + "why_helpful": "This matches the exact syntax pattern used in Option A, allowing a student to recognize the structure.", + "why_maybe_unnecessary": "Some students might infer it from the 'word_lengths' question if the solution to that question used a comprehension.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: result = dict(zip(keys_list, values_list))", + "why_helpful": "Explicitly validates Option B's logic for students who have never seen zip().", + "why_maybe_unnecessary": "Option B is quite intuitive if 'zip' is assumed to 'pair things up', but for zero-knowledge, it needs proof.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:44:19Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q10", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q10", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-2", + "question": "You have a dictionary called grades, in which the keys are unique student ID's (as strings) and the corresponding values are each student's Python course grades (as floats).\n\nYou'd like to create another dictionary called grade_curve, in which the keys are the 18 possible Dutch course grades (1.0, 1.5, 2.0, ..., 10) as floats, and the corresponding (integer) values are the number of students in grades who have that particular grade.\n\nTake a look at the following code segment to create the grade_curve dictionary.\n\ndutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0,\n 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}\n\nDo you think this code segment will always work as intended? If not, then why not?", + "options": { + "a": "Yes, the code will always work as intended.", + "b": "The code will not work as intended if there are certain grades that no student has received. That will lead to an error in constructing the dictionary comprehension.", + "c": "The code will not work as intended, because the keys of the grades dictionary are not used in the list comprehension inside the sum function.", + "d": "The code will not work as intended, because including a list comprehension inside a dictionary comprehension will lead to a Python syntax error." + }, + "correct": "a", + "explanation": "The inner comparison list produces True and False values for every grade entry, and sum counts the matches, including zero when no student received that grade.", + "code_context": "dutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet describes creating a 'grade_counts' dictionary to count student frequencies per grade, which is the exact logical goal of the exam question, though it doesn't show the inner boolean sum implementation." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Directly relates to the problem domain of counting student grades in a dictionary format." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Confirms the syntax and validity of using dictionary comprehensions to map keys to computed values." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides another clear example of a dictionary comprehension creating mapping between a source list and a calculated property." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Establishes the intended outcome (frequency mapping)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Establishes dictionary comprehension syntax." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Mentions the 'sum' function used on values, confirming it as a valid built-in for numeric totals." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets verify the outer structure (dictionary comprehension) and the goal (counting grades), but no snippet explains that 'sum' can process a list of booleans (True/False) by treating them as 1 and 0. A student with zero knowledge might still doubt if sum([True, False]) is valid.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main conceptual hurdle is the implicit conversion of Booleans to integers during a sum operation, and the behavior of an empty match (summing all False values).", + "missing_concepts": [ + "Boolean to Integer coercion (True=1, False=0)", + "Summation of a boolean list", + "List comprehension producing booleans via equality checks" + ], + "proposed_fix": "Add a snippet or detail explaining how boolean conditions like 'x == y' inside a list comprehension interact with the sum() function." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: count = sum([val == target for val in collection]). Show that this results in an integer, even if the count is zero.", + "why_helpful": "This is the core 'trick' of the exam question. Without seeing that sum handles booleans, a student might incorrectly choose options B or D.", + "why_maybe_unnecessary": "The student might infer it if they see 'grade_counts' examples that work, but it's a leap for a 'zero knowledge' persona.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:44:39Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q11", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q11", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-1", + "question": "What does the following code segment print to the screen?\n\nfrom datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "options": { + "a": "26-03-2020", + "b": "04-24-2020", + "c": "15-04-2020", + "d": "05-14-2020" + }, + "correct": "a", + "explanation": "The string is parsed as 5 April 2020 using month.day.year format, and subtracting 10 days yields 26 March 2020, which is then formatted as day-month-year.", + "code_context": "from datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-parse", + "rationale": "Provides a clear example of `strptime` where the student can map the input string '2024-05-20' to the format codes '%Y-%m-%d', allowing them to infer that %m is month and %d is day." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-parse", + "rationale": "Shows how to parse strings and allows mapping of specific format codes (%m, %d, %Y) to date components." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Explains that adding a `timedelta` to a `datetime` shifts the date, which is necessary for the `date + timedelta(days=-10)` calculation." + }, + { + "item_id": "ks-755c23c4be", + "rationale": "Explicitly defines format codes like %m for month and %Y for year, and explains the purpose of `strftime`." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-parse", + "rationale": "Essential for understanding `strptime` and inferring format codes." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Essential for understanding date arithmetic with `timedelta`." + }, + { + "item_id": "ks-755c23c4be", + "rationale": "Essential for understanding `strftime` and confirming month/year codes." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of snippets allows a student to decode the format string in `strptime` (04 is month, 05 is day), understand that adding a negative timedelta subtracts days, and finally format the result back into a string using the same codes.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are sufficient because they provide both explicit definitions and enough example context to infer the meaning of the format codes and the behavior of the arithmetic.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:44:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q12", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q12", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-2", + "question": "Suppose you have the following definition for a Meeting class, which records basic information about meetings in a calendar application.\n\nYou would like to add a method called lunch_meeting to this class, which returns a boolean value indicating whether there is any overlap between the official lunchtime (12:30 - 13:00) and the time of the meeting.\n\nFor example, if you construct a Meeting object as:\nmy_meeting = Meeting('Ask for salary raise', \"25-05-2022\", start_time='12:00', length=45)\nthen the method call:\nmy_meeting.lunch_meeting()\nshould return the boolean value True.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = lunch_start + timedelta(minutes=30)\n return self.start < lunch_end and self.end > lunch_start", + "b": "def lunch_meeting(self):\n return self.start < \"13:00\" and self.end > \"12:30\"", + "c": "def lunch_meeting(self):\n return start_time <= \"13:00\" and start_time + length > \"12:30\"", + "d": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = datetime(self.date.year, self.date.month, self.date.day, 13, 0)\n return self.start >= lunch_end or self.end <= lunch_start" + }, + "correct": "a", + "explanation": "Option A constructs the lunch interval on the same date and uses the standard interval-overlap check. The other options compare datetimes to strings, reference names that are not in scope, or use the non-overlap condition instead.", + "code_context": "from datetime import datetime, timedelta\n\nclass Meeting:\n def __init__(self, topic, date, start_time=\"09:00\", length=30):\n self.topic = topic\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day,\n int(start_time.split(':')[0]), int(start_time.split(':')[1]))\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to define a method within a class that compares attributes using boolean logic, which is the structural requirement for the lunch_meeting method." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates method definition and attribute comparison logic (higher score and more reviews)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows basic class attribute initialization, helping a beginner understand what 'self.date' or 'self.start' represents." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Illustrates calling methods on an object instance, which helps clarify the 'my_meeting.lunch_meeting()' context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Method syntax and comparison logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Class/Attribute structure." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the available snippets mention the 'datetime' or 'timedelta' modules. A student with zero knowledge would not know how to construct a datetime object, that you can't compare a datetime object to a string (Option B/C), or the syntax for adding time using timedelta.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The provided snippets focus on OOP basics and Pandas, entirely missing the 'datetime' module which is central to the question.", + "missing_concepts": [ + "datetime.datetime constructor syntax", + "datetime.timedelta usage for time arithmetic", + "Comparison rules between datetime objects and strings", + "Interval overlap logic (A < End2 and B > Start2)" + ], + "proposed_fix": "Add a summary snippet or an exam question snippet that specifically covers the datetime library, showing object creation and timedelta addition." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Topic Detail' or 'Cheat Sheet' item for Week 8 (Datetime) covering: 1. datetime(year, month, day, hour, minute) 2. timedelta(minutes=N) 3. Comparing datetimes using <, >, ==.", + "why_helpful": "This would give the student the specific syntax needed to evaluate Options A and D, and recognize that Option B/C are invalid comparisons.", + "why_maybe_unnecessary": "Only unnecessary if the student is expected to infer library usage from the provided 'code_context' in the question, but 'zero knowledge' implies they need a reference.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:45:33Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q13", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q13", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Basic logic 2", + "question": "Suppose you have a variable x which contains a list of tuples, as follows:\n\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nChoose the correct output for the following line of code.\n\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "options": { + "a": "True", + "b": "False", + "c": "NameError", + "d": "SyntaxError" + }, + "correct": "a", + "explanation": "The left-hand side is 2 * 3 = 6 and the right-hand side is 8 - 2 = 6, so the comparison evaluates to True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This snippet uses the exact same list 'x' and explains the logic for a very similar boolean comparison, showing how specific indices map to numerical values (e.g., 2 * 3 == 6)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Directly matches the data structure 'x' and provides evaluation examples for index-based arithmetic." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Provides redundant confirmation of the evaluation logic for the same variable 'x' and tuple-in-list structure." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions string/list indexing and slicing which helps a student understand the concept of 0-based indexing used in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Provides the exact list content and a mapped numerical result for a nearly identical expression." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets essentially contain the answer key for a previous version of this exact question, mapping the indexing operations to the numerical values (2, 3, 6, etc.) needed to solve it.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the student can 'match' the patterns from the snippets to get the answer, there is no explicit rule provided for negative indexing (e.g., -1 is the last item).", + "missing_concepts": [ + "negative indexing rules", + "nested indexing (list of tuples) mechanics" + ], + "proposed_fix": "Add a snippet from a lecture or guide that explicitly defines that x[-1] refers to the last element and x[0] refers to the first." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining Python's negative indexing (e.g., index -1 is the last item, -2 is second to last) and nested indexing (e.g., x[0][1] accesses the second element of the first item).", + "why_helpful": "It would move the student from 'pattern matching' against old exams to actually understanding the logic required to solve the indexing math independently.", + "why_maybe_unnecessary": "The existing exam snippets are so similar that the student will likely find the answer by visual comparison alone.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:45:52Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q14", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q14", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Basic loop 2", + "question": "Which of the following code segments will print every even number between 0 and 20 (including 0 and 20) to the screen?", + "options": { + "a": "for i in range(0, 20):\n if i % 2 == 0:\n print(i)", + "b": "i = 0\nwhile i <= 20:\n if i % 2 == 0:\n print(i)\n i += 1", + "c": "for i in list(range(0, 20)):\n print(i if i % 2 == 0 else None)", + "d": "i = 0\nwhile i < 21:\n print(i)\n i += 1" + }, + "correct": "b", + "explanation": "Option B checks every integer from 0 through 20 inclusive and prints only the even ones. Option A never reaches 20, option C also prints None for odd numbers, and option D prints every number.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "This snippet demonstrates the modulo operator (% 2 == 0) for checking parity and introduces the range function, both of which are central to identifying the correct code segment in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Shows the syntax for checking if a number is even (i % 2 == 0) and how the range function is structured." + }, + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Explicitly confirms that specific programs (likely using modulo) correctly identify odd vs even numbers, reinforcing the concept needed for the 'if i % 2 == 0' filter." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "The explanation clearly states that 'while i < 11' runs from 1 to 10, which helps a student understand the exclusive boundary logic required to evaluate 'range(0, 20)' and 'while i < 21'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Introduces modulo parity checks and the range function." + }, + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Validates the use of the modulo operator for even/odd detection." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Explains exclusive loop boundaries (i < 11 means up to 10)." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover parity checking and the 'exclusive' nature of loop boundaries (i < 11). However, they don't explicitly state that range(0, 20) also follows this exclusive stop rule, requiring the student to make an inferential leap from while-loop boundaries to range-function boundaries.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main missing piece is a clear explanation of how range(start, stop) behaves regarding the upper bound.", + "missing_concepts": [ + "Explicit definition of range(start, stop) upper-bound exclusivity.", + "Direct comparison between i <= 20 (inclusive) and i < 21 (exclusive)." + ], + "proposed_fix": "Add a snippet or detail that explains the range(start, stop) parameters clearly, specifically noting that 'stop' is not included." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining the range() function: range(0, 10) produces numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The number 10 is not included.", + "why_helpful": "This directly addresses the confusion between range(0, 20) and range(0, 21) which is the primary distractor in options A and C.", + "why_maybe_unnecessary": "Students might infer it from the 'while i < 11' explanation, but it is a risky assumption for a total beginner.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:46:16Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q15", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q15", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Basic scope 2", + "question": "Choose the correct statement about the program below:", + "options": { + "a": "a is a global variable. b, c, d are local variables.", + "b": "a, b are global variables. c, d are local variables.", + "c": "a, b, c, d are global variables.", + "d": "a, c, d are global variables. b is a local variable." + }, + "correct": "a", + "explanation": "`a` is defined at module level, so it is global. `b` is local to `outer`, and `c` and `d` are local to `inner`.", + "code_context": "a = 1\ndef outer(b):\n b = 2\n def inner(c):\n d = 3\n return a + c + d\n return inner(4) + b" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Explicitly defines global names (outside functions) and local names (parameters + assignments inside functions), which allows direct categorization of a, b, c, and d." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the foundational rules for distinguishing global vs local scope based on definition location and parameters." + }, + { + "item_id": "manual-scope-local-name", + "rationale": "Reinforces that parameter names (like b and c) are local and do not exist outside the function body." + }, + { + "item_id": "ks-f069ee6a0b", + "rationale": "Explains that functions can be defined inside other functions, validating the 'inner' and 'outer' structure shown in the code." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Covers the rules for a (outside), b/c (parameters), and d (assignment inside)." + }, + { + "item_id": "ks-f069ee6a0b", + "rationale": "Clarifies the nested function structure used in the code context." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "ks-2a6510492d provides precise definitions for both global variables (defined outside) and local variables (parameters or assigned inside). A student can apply these rules to identify 'a' as global and 'b, c, d' as local without needing prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective. The only minor ambiguity for a complete novice might be whether a variable local to an 'inner' function counts as 'local' in a general sense, but the definitions provided are broad enough to cover this.", + "missing_concepts": [ + "Explicit confirmation that 'local' as a general term includes variables in nested scopes (non-local/closure variables)." + ], + "proposed_fix": "Add a note to the 'Global and local scope' lecture snippet stating that any variable defined inside a function (regardless of nesting level) is considered local relative to the global scope." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-2a6510492d", + "proposal": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). This applies to all functions, including those nested inside others. Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates).", + "why_helpful": "It explicitly bridges the gap between simple local variables and variables defined in nested function structures, which is the core of this specific exam question.", + "why_maybe_unnecessary": "The current definition 'defined inside a function' already technically covers nested functions, and the exam options don't require distinguishing between 'local' and 'non-local'.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:46:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q16", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q16", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-1", + "question": "You have to write a function called main, which takes a list of unique integers as an argument and returns a dictionary.\n\nThe output dictionary should consist of all key-value pairs for which the key is an element of the input list and the value is the next element of the input list. When there is no \"next element\" any more, leave the key-value pair out of the dictionary.\n\nFor example, if your function is called as:\nmain([1, 3, 2, 4])\nthen it should return the dictionary:\n{1: 3, 3: 2, 2: 4}\n\nWhich of the following programs work(s) according to the requirements?", + "options": { + "a": "def main(l1):\n result = {}\n index = 0\n while True:\n index = index + 1\n if index >= len(l1):\n break\n else:\n result[l1[index]] = l1[index + 1]\n return result", + "b": "def main(l1):\n result = {}\n for index, value in zip(l1[:-1], l1[1:]):\n result[index] = value\n return result", + "c": "Both programs work as required", + "d": "Neither of the two programs works as required" + }, + "correct": "b", + "explanation": "Option B correctly zips each element with the following element and builds the required dictionary. Option A starts at index 1 and eventually tries to access past the end of the list.", + "code_context": "main([1, 3, 2, 4])\n# should return {1: 3, 3: 2, 2: 4}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "It demonstrates the fundamental pattern of initializing an empty dictionary (`y = {}`) and populating it within a loop, which is the basic structure used in both code options." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows dictionary initialization and population logic which is central to the question's code structure." + }, + { + "item_id": "aiq-5", + "rationale": "Shows a function taking a list and returning a dictionary populated with specific keys and values derived from that list." + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Discusses returning pairs of numbers from a list, which conceptually aligns with the 'key-next element' pairing requirement." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Basic dictionary/loop pattern." + }, + { + "item_id": "aiq-5", + "rationale": "Function returning a dictionary from a list input." + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Context for pairing logic." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Reinforces dictionary key-value mapping concepts." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the available snippets explain list slicing (e.g., `l1[:-1]`) or the `zip()` function, which are essential to understand why Option B works. Furthermore, there are no examples of 'while' loops with index manipulation that would help a student realize why Option A fails (incorrect starting index and boundary risk).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets cover basic dictionary creation but lack technical details on sequence iteration and pairing.", + "missing_concepts": [ + "zip() function for parallel iteration", + "list slicing (e.g., list[:-1] and list[1:])", + "while loop indexing and off-by-one errors" + ], + "proposed_fix": "Add a snippet or AI-generated example specifically demonstrating how to pair adjacent elements in a list using both zip/slicing and indexed loops." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Idioms' snippet: 'To pair adjacent elements in a list `L`, use `zip(L[:-1], L[1:])`. This creates pairs of (current, next). Alternatively, an indexed loop would use `range(len(L)-1)` to avoid an index-out-of-bounds error when accessing `L[i+1]`.'", + "why_helpful": "It directly explains the syntax used in the correct answer (Option B) and clarifies the boundary conditions that make Option A incorrect.", + "why_maybe_unnecessary": "If the course focuses more on manual indexing than built-in idioms, but given it appears on the exam, it is necessary.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:46:56Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q17", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q17", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-2", + "question": "What will be printed by the following program?", + "options": { + "a": "True", + "b": "False", + "c": "An error message", + "d": "None" + }, + "correct": "a", + "explanation": "Dictionary equality compares key-value contents rather than insertion order. Since both dictionaries contain the same pairs, the comparison prints True.", + "code_context": "d1 = {1: 5, 4: 6}\nd2 = {4: 6, 1: 5}\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet explicitly explains how the equality operator (==) works in Python, providing concrete examples of True/False results for comparisons, which helps a student understand the mechanism being tested." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Establishes the behavior of the == operator for different types and boolean evaluation." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the syntax for a dictionary with integer keys and values, similar to the question's context." + }, + { + "item_id": "aiq-3", + "rationale": "Provides a trace of dictionary operations, helping the student recognize dictionary structure and key-value relationships." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Teaches equality operator behavior." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows dictionary key-value pair syntax." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets explain the '==' operator and show dictionary syntax, none of the provided materials explain that dictionaries are unordered collections where equality is based on content rather than insertion order. A student with zero knowledge might incorrectly assume order matters (like in a list).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing the specific rule that Python dictionaries compare equal if they have the same key-value pairs, regardless of order.", + "missing_concepts": [ + "Dictionary equality logic (content vs. order)", + "Unordered nature of dictionary comparisons" + ], + "proposed_fix": "Add an AI-generated question or a lecture snippet that explicitly compares two dictionaries with identical content but different key-value ordering." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'In Python, two dictionaries are considered equal (==) if they contain the same set of key-value pairs. The order in which the pairs were added does not affect equality. Example: {1: 'a', 2: 'b'} == {2: 'b', 1: 'a'} is True.'", + "why_helpful": "Directly addresses the core concept of the exam question which is currently completely unrepresented in the available snippets.", + "why_maybe_unnecessary": "Only unnecessary if we want students to guess based on general intuition that 'content is what matters', but that is risky for an exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:47:13Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q18", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q18", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-3", + "question": "d1 = {1: 2, 2: 1}\n\nThe following code segments all print exactly the same output, except for one. Which one?", + "options": { + "a": "result = 1\nfor x in d1.values():\n result *= x\nprint(result)", + "b": "result = -1\nfor x in d1.keys():\n result += d1[x]\nprint(result)", + "c": "result = 4\nfor x in d1.items():\n result = result // x[1]\nprint(result)", + "d": "result = -4\nfor x in d1:\n result /= d1[x]\nprint(result)" + }, + "correct": "d", + "explanation": "A, B, and C all print 2. Option D uses true division starting from -4, so it prints -2.0 instead, making it the odd one out.", + "code_context": "d1 = {1: 2, 2: 1}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "This snippet explicitly explains that iterating directly over a dictionary (as seen in option D) only yields keys, which is the most critical conceptual hurdle for this specific question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Clarifies that direct dictionary iteration (for x in d1) yields keys, aiding the evaluation of option D." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Introduces the .values() and .keys() methods, which are central to options A and B." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates accessing dictionary values using specific keys, which is necessary for options B and D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Covers direct iteration logic." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Covers .keys() and .values() methods." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Covers value retrieval by key." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover dictionary iteration methods and key-based access, there is no information regarding the .items() method, how to index into the resulting tuples (x[1]), or the distinction between floor division (//) and true division (/). A student would likely struggle to calculate the results for options C and D accurately.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gaps are the lack of information on the .items() method and the behavioral difference between the two types of division operators in Python.", + "missing_concepts": [ + ".items() method return format (list of tuples)", + "Tuple indexing (e.g., x[1])", + "Floor division (//) vs True division (/)" + ], + "proposed_fix": "Add a snippet or detail card that explains the .items() method and provides a comparison of division operators, including their effect on resulting data types (integer vs. float)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating dictionary iteration using .items() (e.g., 'for k, v in d.items()') and clarifying that 'for x in d.items()' makes 'x' a tuple where 'x[1]' is the value. Also include a clear distinction between // (integer/floor division) and / (true division).", + "why_helpful": "This would directly enable the student to solve option C (understanding items and indexing) and D (recognizing why the division results in a different value/type).", + "why_maybe_unnecessary": "If the student can guess that .items() provides both key and value and that x[1] follows standard indexing, but the division distinction is rarely intuitive to non-programmers.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:47:44Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q19", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q19", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-1", + "question": "Suppose that you have a string called s1, which contains several letters. The letter \"x\" and the letter \"y\" occur exactly once in the string, and \"x\" always precedes \"y\".\n\nYou'd like to print out a string that looks just like s1, except that the letters \"x\" and \"y\" should be swapped.\n\nFor example, if:\ns1 = \"axbyc\"\nthen you'd like to print:\naybxc\n\nReminder: The replace string method has a third argument, which allows you to specify the maximum number of replacements you want to make, counting from left to right.", + "options": { + "a": "s1 = s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "b": "s1 = s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)", + "c": "s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "d": "s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)" + }, + "correct": "b", + "explanation": "Option B first changes the single y to x, then changes the first x from left to right back to y, which swaps the two letters. Options C and D do not assign the new string back to s1, and A changes the first replacement back incorrectly.", + "code_context": "s1 = \"axbyc\"\n# desired printed result: aybxc" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "While it focuses on pandas .map() and .split(), it is the only snippet categorized under 'String Fundamentals' that mentions applying transformations to string values, though it lacks the critical explanation of .replace()." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides the closest context for string manipulation logic, even if the specific methods differ." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions formatting a string by removing characters (dashes), which implies string cleaning/replacement logic, though the code is not visible." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Shows a problem involving string parsing (TLD extraction), reinforcing that strings are handled through specific method calls." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Establishes the concept of transforming string data." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain the 'replace' method, its optional 'count' argument, or the fundamental concept of string immutability (which explains why s1 = s1.replace... is required). A student with zero knowledge could not distinguish between the options based on this data.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus on high-level data structures (DataFrames, Lists of Dictionaries) or specific complex functions (anagrams, TLDs) rather than basic string methods and object immutability.", + "missing_concepts": [ + "String immutability (methods return a new string; original is unchanged)", + "The .replace(old, new, count) method syntax and behavior", + "Variable reassignment logic for string updates" + ], + "proposed_fix": "Add a foundational snippet covering basic string methods (replace, strip, split) that explicitly mentions they return new objects and explains the optional 'maxreplace' argument." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Methods and Immutability. Content: Strings in Python are immutable; methods like .replace() return a NEW string rather than modifying the original. Usage: s.replace('old', 'new', 1) replaces only the first occurrence.", + "why_helpful": "This directly addresses the mechanics required to solve the question: the need for assignment (s1 = ...) and the effect of the third argument.", + "why_maybe_unnecessary": "If the course assumes students already know basic string manipulation from earlier weeks, but the prompt specifies 'zero prior knowledge'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:04Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q20", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q20", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-2", + "question": "Take a look at the following function definition.\n\nWhat will be returned by the following function call:\nglue(a='e', b='d')", + "options": { + "a": "ab", + "b": "cd", + "c": "ba", + "d": "dc" + }, + "correct": "c", + "explanation": "The function iterates over the keyword names in insertion order (`a`, then `b`) and prepends each key to the current result. Starting from the empty string, that produces `a`, then `ba`.", + "code_context": "def glue(**kwargs):\n result = ''\n for el in kwargs.keys():\n result = el + result\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Explains that a function accepting a flexible number of keyword arguments (which corresponds to **kwargs in the code) uses those arguments like a collection, helping the student identify the source of 'kwargs'." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Identifies that keyword arguments passed to a function are handled as a group (the **kwargs pattern)." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows a 'for key in x' loop structure where 'key' is used to iterate through a collection, which parallels the loop in the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Shows string manipulation logic in functions, which is the secondary operation in the question (concatenating strings)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Connects the function call glue(a='e', b='d') to the concept of keyword arguments." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Demonstrates the syntax for iterating through a set of keys in a dictionary-like object." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "medium", + "rationale": "While the snippets explain what keyword arguments are and how loops work, they do not explicitly state that 'kwargs.keys()' returns the parameter names ('a', 'b') as strings. A zero-knowledge student might reasonably assume 'el' refers to the values ('e', 'd') or the combined pairs without a specific reference to the .keys() method.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no snippet that explains the mapping between keyword argument names (the keys) and their values within the **kwargs dictionary, specifically how .keys() behaves.", + "missing_concepts": [ + "**kwargs keys as parameter name strings", + "dict.keys() return values", + "string prepending order (el + result vs result + el)" + ], + "proposed_fix": "Add a snippet or AI common question that explicitly traces a function using **kwargs.keys() to show it yields the names of the arguments as strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Understanding **kwargs and .keys(). Code: def show_keys(**kwargs): return list(kwargs.keys()). Call: show_keys(first='val1', second='val2'). Output: ['first', 'second'].", + "why_helpful": "This would explicitly teach the student that the 'keys' in keyword arguments are the names used in the call, not the values assigned to them.", + "why_maybe_unnecessary": "One might argue that 'keys' is a semantically intuitive word, but in programming 'key' vs 'value' is a specific distinction that needs defining for a novice.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:22Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q21", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q21", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-3", + "question": "Take a look at the following function definition.\n\nWhat will be printed to the screen by the following code?\nprint(tester())", + "options": { + "a": "1", + "b": "-1", + "c": "0", + "d": "None" + }, + "correct": "a", + "explanation": "The default argument is `0`, which satisfies the non-negative condition, so the function returns `1` and `print` outputs `1`.", + "code_context": "def tester(i1 = 0):\n if i1 >= 0:\n return 1\n\n if i1 < 0:\n return -1" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explicitly demonstrates function definitions with multiple default arguments and shows the results of calling the function when some arguments are omitted." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Covers the core mechanic of default arguments (num2=10, num3=20) being used when not provided in the call." + }, + { + "item_id": "manual-print-vs-return", + "rationale": "Explains the fundamental flow: a function returns a value to the caller, which can then be displayed using the print() function." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Provides a direct example of a function called with one argument where the second defaults (y=11), matching the structure of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Teaches default argument behavior." + }, + { + "item_id": "manual-print-vs-return", + "rationale": "Teaches how 'return' values interact with 'print()'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets clearly explain that if an argument is not provided (tester()), the default value (i1=0) is used, and that the value 'returned' by the function is what 'print' displays.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover the logic well. A minor gap is the explicit definition of comparison operators like '>=' for complete beginners, though they are mathematically intuitive.", + "missing_concepts": [ + "Comparison operator syntax (>=, <)" + ], + "proposed_fix": "Add a small reference snippet for common comparison operators." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: Comparison Operators. x >= y means 'x is greater than or equal to y'. x < y means 'x is less than y'. Example: 0 >= 0 is True.", + "why_helpful": "Ensures a student with zero coding background doesn't second-guess the meaning of the mathematical symbols in Python.", + "why_maybe_unnecessary": "Most students recognize >= and < from basic math.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q22", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q22", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "List lambda 2", + "question": "Assume that you have a variable called x, which contains a list of integers.\n\nWhich of the following code segments will create another list that has every element of x multiplied by 2?\n\nFor example, if\nx = [1, 2, 3, 4, 5]\nthen which of the following code segments will result in the list:\n[2, 4, 6, 8, 10]", + "options": { + "a": "list(map(lambda i : i * 2, x))", + "b": "[(lambda i : i * 2)(item) for item in x]", + "c": "y = lambda i : i * 2\n[y(i) for i in x]", + "d": "All three code segments would work as intended" + }, + "correct": "d", + "explanation": "Each option constructs the doubled list correctly: `map` with a lambda, an immediately called lambda inside a list comprehension, and a named lambda used inside a list comprehension all apply `i * 2` to every element of `x`.", + "code_context": "x = [1, 2, 3, 4, 5]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "This snippet asks how to create a list of squared values from an existing list 'x', which is structurally identical to the target question's goal of doubling values. It likely demonstrates the list comprehension or mapping pattern needed." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Provides the closest structural analogy for transforming a list of integers into a new list of transformed integers." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explicitly mentions the .map() method and its purpose in applying a function to elements, helping to validate Option A." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Establishes the pattern for list-wide operations." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces the concept of mapping a function over a collection." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets hint at list transformations and the map() function, none of the available snippets define or explain the 'lambda' keyword or the specific syntax of immediately invoked lambdas within list comprehensions. A student with zero knowledge would not be able to confirm if 'lambda i : i * 2' is correct syntax.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of 'lambda' syntax explanation in the recommended snippets.", + "missing_concepts": [ + "Lambda function syntax (lambda arguments : expression)", + "Immediately Invoked Function Expressions (IIFE) in Python", + "Differences between named functions and lambdas in comprehensions" + ], + "proposed_fix": "Add a dedicated reference snippet or topic card covering 'Anonymous Functions (Lambda)' that shows its usage in map() and list comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a topic card titled 'Lambda Functions and List Mapping'. It should show: 1. `list(map(lambda x: x*2, my_list))`, 2. `[ (lambda x: x*2)(i) for i in my_list ]`, and 3. `f = lambda x: x*2; [f(i) for i in my_list]`.", + "why_helpful": "This would directly address all three options (a, b, and c) in the question, allowing a student to recognize the patterns as equivalent.", + "why_maybe_unnecessary": "Only unnecessary if the student is expected to already know basic functional programming concepts, but the prompt assumes zero knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q23", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q23", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "List logic 2", + "question": "Which of the following programs creates a new list y, in which the elements are those elements of list x that are equal to their indices?\nYou can assume x consists of unique integers.\n\nFor example, if:\nx = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\nthen the program should create a new list y such that:\ny = [0, 3, 6, 7, 8, 10]", + "options": { + "a": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(i)", + "b": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(j)", + "c": "y = [i for i in x if i == x.index(i)]", + "d": "All three programs would work as intended" + }, + "correct": "d", + "explanation": "In A and B, whenever `i == j`, appending either `i` or `j` gives the same value because the index equals the element. In C, `x.index(i)` returns the position of `i`, so the comprehension keeps exactly the elements equal to their indices. Therefore all three programs work.", + "code_context": "x = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\n# target result:\ny = [0, 3, 6, 7, 8, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This snippet involves converting a sequence to a list and relates to loop logic, which is the closest match to the list construction required in the question, although it does not explain enumerate or index." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides context on list creation and looping logic." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a 'boolean mask on the index', which introduces the concept of filtering a collection based on index positions, even though it is in a Pandas context." + }, + { + "item_id": "exam-midterm_2023-11-w3-higher-order-patterns", + "rationale": "Discusses functions that accept lists and return new modified lists, which aligns with the structural goal of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Essential for understanding basic list and loop interactions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Connects index-based filtering to result outcomes." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets explain the specific Python built-ins 'enumerate()' or 'list.index()', nor do they provide examples of list comprehension syntax. A student with zero knowledge would not be able to distinguish between using index 'i' vs value 'j' in the enumerate options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate pool lacks any explanation of the 'enumerate' function, the '.index()' method for lists, and the syntax/logic for list comprehensions.", + "missing_concepts": [ + "enumerate() function", + "list.index() method", + "List comprehension syntax" + ], + "proposed_fix": "Add a snippet from Week 2 or 3 course material that explicitly defines 'enumerate' and its return values (index, element), and another that demonstrates basic list comprehensions with an 'if' condition." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining 'enumerate(iterable)': 'The enumerate() function adds a counter to an iterable and returns it as an enumerate object. Example: for index, value in enumerate(['a', 'b']): print(index, value) outputs 0 a and 1 b.'", + "why_helpful": "Directly explains how variables 'i' and 'j' are populated in the loop options (a and b).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining list comprehensions: '[expression for item in list if condition] creates a new list by applying the expression to each item that meets the condition.'", + "why_helpful": "Enables the student to understand the syntax of Option C.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:49:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q24", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q24", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "List loop 2", + "question": "Assume that you have a list called x, which is a list of multiple sub-lists containing integers.\n\nWhich of the following programs will create a new list y that is equal to the sub-list of x whose sum of elements is the highest?\n\nYou can assume that the sum of elements in each sub-list is a different number, so that there is only one that is the highest.\n\nFor example, if:\nx = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\nthen y should be:\ny = [8, 20, 300]", + "options": { + "a": "y = max(x)", + "b": "z = []\nfor i in x:\n z.append(sum(i))\ny = x[z.index(max(z))]", + "c": "x.sort()\ny = x[-1]", + "d": "y = [i for i in x if sum(i) == max(x)]" + }, + "correct": "b", + "explanation": "Option B computes the sum of each sub-list, finds the position of the largest sum, and then returns the corresponding original sub-list. The other options compare lists lexicographically or compare a numeric sum against `max(x)`, which is a list.", + "code_context": "x = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\n# target result:\ny = [8, 20, 300]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Shows the basic structure of iterating through a list 'x' and performing operations on its elements to create a new result, which is the core logic of the loop in Option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Demonstrates looping over a list 'x' to generate a new list of transformed values." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Mentions a function that 'sums even integers' in a list, introducing the 'sum()' concept which is critical for calculating sub-list totals." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Introduces list sorting and manipulation, which helps contrast with the lexicographical comparison mentioned in the explanation (Option C)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Basic list iteration pattern." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduction to 'sum()' behavior." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "General list behavior and comparison context." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows mapping elements from a list to another structure (dictionary), similar to how indices map 'z' to 'x'." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While iteration and summing are touched upon, no snippet explains the 'list.index()' method or the specific logic of finding the maximum value's position to retrieve an item from a parallel list. A student would struggle to identify Option B as correct without knowing how '.index()' and 'max()' interact.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets fail to cover list search methods and the pattern of index-based retrieval.", + "missing_concepts": [ + "list.index()", + "max() function on numeric lists", + "Parallel list indexing (using index of one list to access another)" + ], + "proposed_fix": "Add a snippet demonstrating how to find the index of a specific value (like the maximum) in one list and use it to retrieve data from a corresponding list." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'prices = [10, 50, 20]; max_price = max(prices); best_index = prices.index(max_price); items = [\"apple\", \"pear\", \"banana\"]; print(items[best_index])'", + "why_helpful": "This directly demonstrates the index-retrieval pattern used in the correct answer (Option B).", + "why_maybe_unnecessary": "If the student already understands that indices link related lists, they might guess it, but it's a specific technical hurdle.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:49:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q01", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q01", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_2", + "question": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\n- If they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\n- If they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?", + "options": { + "a": "if destination in europe:\n print('No passport needed. Bring your ID card.')\nelse:\n print('Please bring your passport.')", + "b": "if destination in europe:\n return 'No passport needed. Bring your ID card.'\nelif destination not in europe:\n return 'Please bring your passport.'", + "c": "for country in europe:\n if destination = country:\n print('No passport needed. Bring your ID card.')\n else:\n print('Please bring your passport.')", + "d": "for country in europe:\n if destination != country:\n return 'Please bring your passport.'\n else:\n return 'No passport needed. Bring your ID card.'" + }, + "correct": "a", + "explanation": "Option A directly checks whether destination is in the list of European countries and prints the correct message in each case. The other options either use the wrong control flow or invalid syntax.", + "code_context": "europe = [...]\ndestination = ..." + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination. You want to write a ", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "This snippet is a perfect contextual match as it contains the exact same question text and scenario, helping the student identify the problem as a known pattern even if it doesn't explicitly provide the code." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Matches the question scenario (Europe list and destination string) exactly." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Provides a reference for the 'Conditions' topic, which is the fundamental logic required (if/else)." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Covers loops and list processing, which helps a student understand why the 'for' loop approaches in options C and D are different from the simple membership check." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Provides the exact scenario context." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While one snippet matches the question text, none of the available snippets explain the syntax or behavior of the 'in' operator for list membership, nor do they clarify the distinction between 'print' and 'return' in this context. A student with zero knowledge would not know that 'destination in europe' is a valid Python expression.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide the scenario context but fail to explain the technical syntax required to solve it.", + "missing_concepts": [ + "Membership operator ('in') for checking if an item exists in a list", + "Basic if-else branching syntax", + "Difference between 'print()' and 'return' (especially outside of functions)" + ], + "proposed_fix": "Add a foundational 'Python Basics' snippet that demonstrates checking if a string is inside a list using 'if x in my_list:'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'List Membership and Branching' with search text: 'To check if a value exists in a list, use the \"in\" operator: if item in my_list:. Use \"else:\" to handle cases where it is not found.'", + "why_helpful": "This directly teaches the 'zero-knowledge' student the exact syntax needed to choose Option A over the incorrect loop or return-based options.", + "why_maybe_unnecessary": "If the student is expected to deduce syntax from other exam questions not listed here.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q02", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q02", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_3", + "question": "Calling the function func_10 will produce an error. Which line of the following code segment produces the error?", + "options": { + "a": "'var_2 = var_1 * var'\nThis line produces the error because func_2() was not called and assigning the value to var_1, thus var_1 was referenced before being defined.", + "b": "'var_1 = var * 2'\nThis line produces the error because Python is confused about which value var should have.", + "c": "'def func_2(var):'\nThis line produces the error because the name var is already used for the argument of func_1() and cannot be used again as the name of the argument for func_2().", + "d": "'return var_2'\nThis line produces the error because one function cannot return two outputs." + }, + "correct": "a", + "explanation": "The inner function func_2 is defined but never called, so var_1 is never assigned before the line var_2 = var_1 * var tries to use it.", + "code_context": "def func_1(var):\n def func_2(var):\n var_1 = var * 2\n return var_1\n var_2 = var_1 * var\n return var_2" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "This snippet is a near-identical match to the exam question, explicitly stating that var_1 is a local variable inside func_2 and that func_2 is never called, which directly explains the error in the provided code." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a direct parallel to the question and explains the specific error (local scope and uncalled function)." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the fundamental rules of local and global scope in Python, which is the core concept needed to understand why the variable is inaccessible." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Directly addresses the error in the code context." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the general rule for local scope names being 'Only known inside the function'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippet 'exam-Trial final...-2-w3-scope' contains the exact logic and explanation for this specific function-nesting error. A student can solve the question by pattern-matching the code structure and reading the snippet's explanation.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets are highly sufficient. The direct match snippet even accounts for the 'function never called' and 'local variable' nuances.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q03", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q03", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[str, int, NoneType, bool, float, str, dict]", + "b": "[str, int, NoneType, bool, float, bool, dict]", + "c": "[str, int, NoneType, bool, float, str, list]", + "d": "[str, float, NoneType, bool, int, str, dict]" + }, + "correct": "a", + "explanation": "The function appends the type of each element in the input list in order: string, integer, NoneType, boolean, float, string, and dictionary.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n list_2.append(type(item))\n return list_2\n\nmain(['abc', 0, None, True, 123.456, 'False', {}])" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What is the output of the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ], + "evidence_topics": [ + "Return Behavior" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet is a direct match for the question. It explicitly maps every element in the question's list ('abc', 0, None, True, 123.456, 'False', {}) to its corresponding Python type (str, int, NoneType, bool, float, str, dict)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Directly provides the answer and mapping for all types in the specific question." + }, + { + "item_id": "ks-cb3a9e3fd2", + "rationale": "Provides a clear reference for 'The 8 types to know' (int, float, str, bool, etc.) with syntax examples, which is fundamental for this topic." + }, + { + "item_id": "exam-extra_practice-11-w1-objects-and-names", + "rationale": "Shows a complex list with various types (string, nested list, tuple, dict, bool, float, int) and illustrates how to determine their types using indices." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Because this snippet is an exact duplicate of the exam question and includes a full explanation of the result, it is sufficient on its own." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior' contains the exact same code and input list, and provides a textual breakdown of every item's type, matching option 'a' perfectly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate snippets are highly effective because they include a direct match for the question. Even without the direct match, the combination of lecture notes on the '8 types' and other exam questions covering 'str vs bool' would allow a student to piece together the answer.", + "missing_concepts": [], + "proposed_fix": "No additions are strictly necessary, though ensuring the '8 types' snippet (ks-cb3a9e3fd2) is not truncated in the UI would be beneficial." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:39Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q04", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q04", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 1", + "question": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\n\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97", + "options": { + "a": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou'}", + "b": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou' if vowel in 'aeiou'}", + "c": "Both of the code segments work correctly.", + "d": "Neither of the code segments work correctly." + }, + "correct": "c", + "explanation": "Both comprehensions produce the same dictionary because the extra condition in option B is always true for characters drawn from 'aeiou'.", + "code_context": "print(vowels_ASCII)\n# expected: {'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values. The ASCII (American", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact text and logic of the exam question, making it the most direct reference for a student." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Identical question match, providing the specific scenario of vowels and ASCII values." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a secondary example of dictionary comprehension syntax ({key: value for ...}), reinforcing the pattern used in the correct answer." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Discusses creating a dictionary from two lists (names/ages) with conditions, which helps explain the 'if' clause logic in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Contains the specific problem statement and variables needed to identify the correct code structure." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question text and logic are present in the 'best_single_snippet'. A student can use pattern matching to identify 'vowels_ASCII' and the dictionary comprehension syntax.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets are sufficient because the exact question is mirrored in the source exam items.", + "missing_concepts": [], + "proposed_fix": "No fix needed; the coverage for this specific question is 100%." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:55Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q05", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q05", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 1", + "question": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = (goals1, goals2, goals3)", + "b": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = [goals1 + goals2 + goals3]", + "c": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = [goals1, goals2, goals3]", + "d": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = (goals1, goals2, goals3)" + }, + "correct": "a", + "explanation": "Option A uses enumerate with start=1 to create the correct match-number keys and stores each triple of goal counts as a tuple. The other options either use the wrong value shape or start indexing from 0.", + "code_context": "player1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\nprint(match_goals)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals score", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "This is an exact match for the question provided. It contains the identical scenario, variables (player goals), and target dictionary structure, making it the most direct reference for a student." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Direct duplicate of the exam question; provides immediate context and the correct logic pattern." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows the general pattern of creating a dictionary from a list and evaluating which code segment works as intended, which mirrors the multiple-choice format." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a dictionary where keys are integers starting from 1 (1 to 5), helping the student understand the 'match numbers starting from 1' requirement." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Provides the exact question and likely the solution/logic required for the player_goals scenario." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Confirms the expected output format for 1-based integer keys in a dictionary." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question being asked. Even without prior Python knowledge, a student can identify the matching variable names and logic structure from the provided reference.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the exact question, but they lack a generic explanation of the 'zip' and 'enumerate' functions which are the core technical components of the correct answer.", + "missing_concepts": [ + "zip() for parallel iteration of multiple lists", + "enumerate() with the start parameter (start=1)", + "tuple vs list notation in dictionary values" + ], + "proposed_fix": "Add a lecture-based or reference snippet that explicitly explains how to use enumerate(list, start=1) to create 1-indexed keys." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining 'Iteration with Counters and Multiple Lists'. Examples: enumerate(mylist, start=1) and zip(listA, listB).", + "why_helpful": "This would allow a student to solve the problem by understanding the syntax (zip and enumerate) rather than just relying on finding a duplicate question.", + "why_maybe_unnecessary": "Since the duplicate question already exists in the exam bank, a student using the cheat sheet specifically for this course would likely find the direct answer anyway.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:51:13Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q06", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q06", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 1", + "question": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?", + "options": { + "a": "sales_subset = [monthly_sales[key] for key in list(monthly_sales.keys())[:3]]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "b": "sales_subset = monthly_sales[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "c": "sales_subset = list(monthly_sales.items())[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "d": "sales_subset = monthly_sales['January':'March']\naverage_sales = sum(sales_subset.values()) / len(sales_subset)\nprint(average_sales)" + }, + "correct": "a", + "explanation": "Option A first collects the values for the first three keys into a list and then computes the average correctly. The other options attempt unsupported dictionary slicing or try to sum tuples instead of numeric values.", + "code_context": "monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You have the following dictionary that represents the monthly sales of a store: monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "This snippet is an exact match for the question scenario, providing the specific dictionary and the objective of calculating average sales for January-March." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Directly contains the question text and scenario." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a similar question structure (multiple choice options a-d) and mentions 'Option A' as a valid solution, reinforcing the pattern." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Shows the concept of summing values from a set of data, which is part of the required calculation in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Provides the exact context needed to identify the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the candidate snippet list. A student can match the 'monthly_sales' dictionary and 'average sales' goal to find the answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact question is present, the snippets do not explicitly explain *why* slicing a dictionary directly fails or that items() returns tuples. This makes answering other similar questions difficult without the exact match.", + "missing_concepts": [ + "Dictionary slicing limitations", + "Type of objects returned by dict.items() (tuples)", + "List comprehension with slicing on keys()" + ], + "proposed_fix": "Add a theoretical snippet explaining that dictionaries are unordered/unsliceable and that list(d.keys())[:n] is the standard way to get a slice of keys." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "proposal": "Ensure the full text including the correct code segment and the explanation (why direct slicing fails) is visible in the snippet search text.", + "why_helpful": "It would provide the 'why' instead of just being a match, allowing the student to learn the underlying rule (no slicing on dicts).", + "why_maybe_unnecessary": "The student can already find the answer by matching the exact question text.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:51:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q07", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q07", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "[1, 4, 3, 8, 5]", + "b": "[2, 4, 6, 8, 10]", + "c": "[1, 2, 3, 4, 5]", + "d": "[2, 2, 6, 4, 10]" + }, + "correct": "a", + "explanation": "The list comprehension doubles only the even numbers and leaves the odd numbers unchanged, so the result is [1, 4, 3, 8, 5].", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x * 2 if x % 2 == 0 else x for x in numbers]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Directly explains that 'x % 2 == 0' in a list comprehension context is used to identify even numbers, which is the core logic required to solve the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the modulo operator for even numbers within a list comprehension." + }, + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Provides another example of 'i % 2 == 0' being used to check parity, reinforcing the concept." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Explicitly states that using a mask to find even numbers involves checking the index/value parity, confirming the logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Covers list comprehension structure and parity check logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain 'x % 2 == 0' as 'even', but none explicitly explain the ternary syntax 'x * 2 if condition else x' used within the comprehension. A student might guess it, but it's not fully defined.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The parity check (modulo) is well-covered, but the specific 'if-else' conditional expression syntax inside a list comprehension is missing.", + "missing_concepts": [ + "ternary conditional expressions (value if condition else other_value)", + "list comprehension with if-else vs list comprehension with just if (filtering)" + ], + "proposed_fix": "Add a snippet or detail explaining the difference between 'if' at the end of a comprehension (filtering) and 'if-else' at the start (transformation)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining: 'In list comprehensions, [expression_if_true if condition else expression_if_false for item in list] transforms every item based on the condition.'", + "why_helpful": "It directly addresses the syntax gap for conditional transformations in comprehensions.", + "why_maybe_unnecessary": "Clever students might infer the 'if-else' logic from general English, but formal confirmation is safer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:51:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q08", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q08", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "['10a', '30c']", + "b": "[10, 20, 30, 40]", + "c": "['a', 'b', 'c', 'd']", + "d": "['10a', '20b', '30c', '40d']" + }, + "correct": "a", + "explanation": "The loop keeps only even indices from enumerate(list1), so it uses indices 0 and 2 and appends the concatenated strings '10a' and '30c'.", + "code_context": "list1 = [10, 20, 30, 40]\nlist2 = ['a', 'b', 'c', 'd']\n\nresult = []\n\nfor index, value in enumerate(list1):\n if index % 2 == 0:\n result.append(str(value) + list2[index])\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "This snippet explicitly shows 'enumerate' being used in a loop to get both an index and a value, along with the modulo operator '%' used to check index parity (i % 2)." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Directly demonstrates the 'enumerate' function and the logic for checking even/odd indices." + }, + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Provides a clear explanation that 'x % 2 == 0' is the standard way to filter for even numbers in Python." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Explains the '.append()' method, which is necessary to understand how the 'result' list is being built." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Covers 'enumerate' and the modulo operator for indices." + }, + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Reinforces the concept of filtering even numbers using % 2." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows how lists are mutated using '.append()'." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Helps the student identify 'str' as the string type, which is relevant for the 'str(value)' call." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets collectively explain the loop structure (enumerate), the conditional logic (modulo for even indices), and the list construction (append). A student can logically deduce that for indices 0 and 2, strings are created and added to the list.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the core logic is covered, there is no explicit explanation of 0-based list indexing (list[index]), string concatenation using the '+' operator, or the specific behavior of the 'str()' function on integers.", + "missing_concepts": [ + "0-based list indexing", + "string concatenation with +", + "str() function for type conversion" + ], + "proposed_fix": "Add a foundational snippet from Week 1 or 2 that demonstrates basic list access and string operations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: labels = ['A', 'B']; msg = str(1) + labels[0]; print(msg). Explanation: str() converts numbers to text, '+' joins text, and [0] accesses the first item in a list.", + "why_helpful": "This fills the 'zero-knowledge' gap regarding the specific syntax of list indexing and string building used in the question.", + "why_maybe_unnecessary": "Indexing and '+' for strings are often considered intuitive enough for students to guess correctly if they understand the loop.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:52:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q09", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q09", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 2", + "question": "Suppose you have a list called mylist. You want to extract every third element starting from index 1 (inclusive) to the last index (inclusive) from that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\n\nthen executing the following command:\nprint(subset)\n\nshould return:\n[15, 30, 45]\n\nWhat should the blanks be filled with?", + "options": { + "a": "1:len(mylist):3", + "b": "0:len(mylist):3", + "c": "1:len(mylist)-1:3", + "d": "0:len(mylist)-1:3" + }, + "correct": "a", + "explanation": "Starting at index 1 and stepping by 3 gives positions 1, 4, and 7, which are 15, 30, and 45. Using len(mylist) as the stop value includes the last valid stepped element.", + "code_context": "subset = mylist[___:___:___]\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\nprint(subset)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "While it focuses on sorting and reversing rather than slicing, it is the only snippet that directly discusses manipulating list elements to achieve a specific output order, which is the closest conceptual match." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Discusses list manipulation and index-based logic (implicit in sorting) to reach a target output list." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions selecting specific indices (2, 4, and 6), which introduces the concept of index-based selection, even though it is in a Pandas context." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Discusses 'extracting' parts of a string, which is conceptually similar to list slicing, although the syntax differs." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Shows that lists can be transformed to reach a specific sequence." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets explain the Python slicing syntax `[start:stop:step]`. A student without prior knowledge would not know that the three blanks correspond to the start index, stop index, and step size, nor would they understand how `len(mylist)` interacts with the stop parameter.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gap is the lack of any reference to list slicing syntax and the interpretation of the colon-separated parameters within brackets.", + "missing_concepts": [ + "List slicing syntax: mylist[start:stop:step]", + "Zero-based indexing (identifying that 15 is at index 1)", + "The use of len() as a stop value to include elements until the end of the sequence" + ], + "proposed_fix": "Add a snippet from a lecture or reference guide that explicitly defines the `[start:stop:step]` syntax and provides a simple example." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Key Concept' snippet for List Slicing: 'To extract a portion of a list, use the syntax mylist[start:stop:step]. start is inclusive, stop is exclusive, and step determines the interval between elements. Example: x[1:10:2] starts at index 1 and takes every 2nd element.'", + "why_helpful": "This directly provides the syntax rules required to decode the question's blanks.", + "why_maybe_unnecessary": "Only unnecessary if the student has already covered basic sequence operations, but the prompt assumes zero prior knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:52:45Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q10", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q10", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_1", + "question": "Suppose you have the following function:\n\nWhat will be printed by the following line of code?\nprint(main())", + "options": { + "a": "True", + "b": "False", + "c": "0", + "d": "None" + }, + "correct": "d", + "explanation": "The default value of x is 0, so neither if-condition runs and the function reaches the end without returning anything, which prints None.", + "code_context": "def main(x = 0):\n if x > 0:\n return True\n\n if x < 0:\n return False\n\nprint(main())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet provides the clearest explanation of default arguments (e.g., num2 = 10), which is essential for a student to understand that the variable 'x' in the question starts with a value of 0." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explains default parameter values, helping the student identify that x equals 0 when the function is called without arguments." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Demonstrates tracing a function call that uses a default argument ('y defaults to 11') and shows how the logic branches based on inputs." + }, + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "rationale": "While the logic is at the top level rather than in a function, it shows how 'if' conditions evaluate and includes 'None' as a possible output option, which might prompt the student to consider it." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Necessary to understand the 'x = 0' default syntax." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Provides a template for tracing function execution flow with default values." + }, + { + "item_id": "aiq-1", + "rationale": "Reinforces how conditional branching ('if' and 'else') determines which code paths are executed." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover default arguments and 'if' logic well. However, no snippet explicitly explains the specific Python rule that a function returns 'None' if it reaches the end of its body without executing a 'return' statement.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gap is the 'implicit return' behavior. A student can deduce x=0 and see that neither 'if x > 0' nor 'if x < 0' will run, but they won't know what happens when a function 'runs out' of code.", + "missing_concepts": [ + "Functions return 'None' by default if no return statement is reached", + "Strict comparison: 0 is not greater than 0, and 0 is not less than 0" + ], + "proposed_fix": "Add a conceptual snippet explaining that functions without an executed return statement implicitly return 'None'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Implicit Return Values' explaining: 'In Python, if a function completes its execution without hitting a return statement, it automatically returns the special value None.'", + "why_helpful": "This is the specific 'trick' of the question. Without this rule, a student with zero knowledge might assume the function causes an error or prints nothing.", + "why_maybe_unnecessary": "Advanced students might guess 'None' by process of elimination if they realize no other value is returned, but it is a specific language feature that warrants a snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:53:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q11", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q11", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_3", + "question": "Suppose you have a variable called x which contains a list of integers as follows:\nx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nWhich of the following lines will produce an output that is different from the rest?", + "options": { + "a": "print(len(x))", + "b": "print(sorted(x, reverse=True)[0])", + "c": "print(x.index(9))", + "d": "print(sum(x[4:6]))" + }, + "correct": "a", + "explanation": "len(x) is 10, while sorted(x, reverse=True)[0] is 9, x.index(9) is 9, and sum(x[4:6]) is 4 + 5 = 9.", + "code_context": "x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "Directly explains the use of len(nums) and sum(nums) in a summary context, covering half of the functions used in the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Explains len() and sum(), which are used in options 'a' and 'd'." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Demonstrates using sorted() with reverse order and basic slicing logic, which helps with options 'b' and 'd'." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Reinforces the concept of sorted(x) in reverse order to obtain a specific list sequence." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Covers len() and sum()." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Covers sorted(reverse=True) and slicing." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover len(), sum(), and sorted(reverse=True). However, the '.index()' method (option 'c') is not explained in any of the provided candidate snippets, which is critical for a student with zero prior knowledge to verify that option 'c' results in 9.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary missing concept is the list '.index()' method. Additionally, while slicing is mentioned, a clear definition of how slicing indices (e.g., [4:6]) map to specific elements would be beneficial.", + "missing_concepts": [ + "list.index() method", + "Zero-based indexing for specific slice ranges like [4:6]" + ], + "proposed_fix": "Add a snippet or detail rule explaining that x.index(value) returns the position (index) of the first occurrence of that value." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point or AI common question explaining built-in list methods: .index(item) to find a position, and clarify that indexing starts at 0.", + "why_helpful": "This would allow the student to evaluate option 'c' (x.index(9)) which evaluates to 9.", + "why_maybe_unnecessary": "If the student infers that 'index' means 'position' and counts from 0, they might guess correctly, but it is not explicitly taught in the snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:53:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q12", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q12", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_1", + "question": "You want to write a function called main which accepts a flexible number of integers as arguments.\n\nThe function should return a dictionary with the following key-value pairs:\n- key 'sum' has a value which is the sum of all the integers passed as arguments\n- key 'pro' has a value which is the multiplicative product of all the integers passed as arguments\n- key 'pow' has a value which is a list of all the squares of the integers passed as arguments\n\nWhich of the following lines of code will complete the function to give what you need?", + "options": { + "a": "x['sum'] = sum(args)\nx['pro'] = 1\nx['pow'] = []\nfor i in args:\n x['pro'] *= i\n x['pow'].append(i**2)", + "b": "x['sum'] = sum(args)\nx['pro'] = i for i in args\nx['pow'] = [i**2 for i in args]", + "c": "for i in args:\n x['sum'] = sum(args)\n x['pro'] *= i\n x['pow'] = [i**2 for i in args]", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "Option A correctly stores the sum, initializes the product accumulator to 1 before multiplying through the arguments, and builds the list of squares for each integer.", + "code_context": "def main(*args):\n x = {}\n\n # missing lines\n # ...\n\n return x" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "Directly demonstrates returning a dictionary with keys and using the sum() function on a list of integers, which covers two major requirements of the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Shows dictionary construction and aggregate functions like sum() and len()." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Provides a template for initializing a dictionary (y = {}) and using a for-loop to populate it, matching the structure of the correct answer." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Validates the '*args' syntax for functions accepting a flexible number of arguments." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Dictionary syntax and sum function." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Loop-based dictionary population pattern." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Flexible argument (*args) syntax." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows another example of a loop inside a function to process an iterable into a dictionary." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover dictionary creation, *args syntax, and the sum() function. However, they do not explain the product accumulation logic (pro = 1, pro *= i) or the power operator (**2), which are necessary to confidently choose option 'a' over distractors.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student can understand how to handle *args and return a dictionary, but lacks information on iterative product calculation and exponentiation syntax.", + "missing_concepts": [ + "product accumulation pattern (initializing to 1)", + "exponentiation operator (**)", + "list.append() method" + ], + "proposed_fix": "Add a snippet demonstrating a function that calculates both a running total and a running product using a loop, including list operations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing a function: def stats(*args):\n total = 0\n product = 1\n squares = []\n for n in args:\n total += n\n product *= n\n squares.append(n**2)\n return total, product, squares", + "why_helpful": "This covers every missing concept: the product identity (1), the *= operator, the ** exponentiation, and the append() method.", + "why_maybe_unnecessary": "If students are expected to know basic operators from other contexts, but for zero Python knowledge, this is critical.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:53:51Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q13", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q13", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 2", + "question": "You have the following objects loaded in Python:\nitem = \"laptop\"\nprice = 1299.99\n\nYou need to print the following sentence:\nThe laptop is priced at $1299.99.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(message)", + "b": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(mesage)", + "c": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)", + "d": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)" + }, + "correct": "a", + "explanation": "Option A correctly uses positional placeholders and prints the defined variable `message`. Option B appears to use a misspelled variable name in the print call, and C/D mix named placeholders with positional arguments.", + "code_context": "item = \"laptop\"\nprice = 1299.99" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "While it focuses on .map() and .split() rather than formatting, it is the only snippet categorized under 'String Fundamentals', though it provides no help for f-strings or .format()." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Categorized under string fundamentals, but content is irrelevant to formatting." + } + ], + "minimal_sufficient_snippets": [], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the candidate snippets explain Python string formatting methods (.format() or f-strings), positional/named placeholders, or the basic requirement that variable names in print() must match their definitions exactly (to catch the typo in option B).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of content regarding string interpolation and formatting syntax.", + "missing_concepts": [ + "The .format() method syntax", + "Positional placeholders ({0}, {1})", + "Named placeholders ({item}, {price})", + "Variable name case-sensitivity and spelling requirements" + ], + "proposed_fix": "Add a source material snippet or exam question that demonstrates the .format() method with both positional and keyword arguments." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining string formatting: 'The .format() method inserts values into strings. Positional placeholders like {0} and {1} correspond to the order of arguments in .format(first, second). Named placeholders like {name} require matching keywords in .format(name=\"value\").'", + "why_helpful": "It directly enables a student to understand why Option A (positional) works and why Options C/D (named vs positional mismatch) fail.", + "why_maybe_unnecessary": "Only if the student already knows Python, but the goal is zero prior knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:54:06Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q14", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q14", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 1", + "question": "Suppose you have run the following block of code:\n\nimport pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)\n\nWhich of the following lines of code give(s) the following output?\n1 4\n2 5\n3 6\nName: B, dtype: int64", + "options": { + "a": "df.loc[:, 'B']", + "b": "df['B'].loc[:]", + "c": "df['B']", + "d": "All of the given lines." + }, + "correct": "d", + "explanation": "Each of A, B, and C selects the same Series containing column `B`, so the correct choice is that all listed lines produce the shown output.", + "code_context": "import pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the standard syntax df['A'] and df['B'] for accessing columns in a DataFrame, which directly validates option 'c' and provides a baseline for Pandas indexing." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates basic column selection using bracket notation." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using df.loc for indexing and selecting specific columns, though it focuses on row filtering." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame and mentions the intent to select data to create new structures." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Validates bracket indexing for columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Introduces the concept of using .loc for selection." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets confirm that df['B'] is valid syntax for selecting a column. However, there is no explicit information explaining that df.loc[:, 'B'] is equivalent or that a Series returned by df['B'] can be further indexed with .loc[:]. A student would likely identify 'c' but might struggle to be certain about 'a' and 'b' without prior knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets show basic bracket indexing but lack examples of multi-axis selection using .loc or the fact that column selection returns a Series object that supports its own indexing.", + "missing_concepts": [ + "pandas .loc multi-axis selection (rows, columns)", + "equivalence of different column selection methods", + "indexing on a Series object returned from a DataFrame" + ], + "proposed_fix": "Add a snippet or detail rule explaining that df.loc[:, 'col'] selects all rows for a column, and that df['col'] returns a Series which itself supports .loc syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet illustrating the equivalence of df['col'], df.loc[:, 'col'], and df.iloc[:, col_index] for column selection.", + "why_helpful": "It directly addresses the core of the question (multiple ways to select the same data) which is a common pattern in introductory Python exams.", + "why_maybe_unnecessary": "Basic bracket notation is often sufficient for simple tasks, but this specific question tests 'all of the above' scenarios.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:54:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q15", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q15", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_1", + "question": "Which code segment gives the same output as the following?\n\ndate = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))\n\nYou may assume that datetime and timedelta classess are already imported from the datetime module.", + "options": { + "a": "print(datetime.strptime('22-05-2023', '%d.%m.%Y'))", + "b": "print('02-05-2023')", + "c": "print(datetime.strptime('05.22.2023', '%d-%m-%Y'))", + "d": "date = datetime.strptime('10/05/2023', '%d/%m/%Y')\nprint((date + timedelta(days=5)).strftime('%m-%d-%Y'))" + }, + "correct": "b", + "explanation": "The original code parses May 12, 2023 and subtracts 10 days, so the printed result is the string `02-05-2023`.", + "code_context": "date = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the most relevant snippet as it explicitly mentions the Datetime module and explains that operations involving datetime objects involve the timedelta class." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Provides the crucial connection between datetime objects and the timedelta class." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Shows example usage of the datetime class and basic arithmetic (subtraction)." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains the print function, which is necessary to understand how the final result is displayed." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Identifies the core library and the timedelta concept." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Demonstrates datetime class syntax." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain the 'strptime' or 'strftime' methods, nor do they define the format codes like %m, %d, or %Y. A student with zero knowledge would not know if '05.12.2023' is May 12th or December 5th, nor would they know how to format the final string.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing core documentation for string-to-date parsing, date-to-string formatting, and the specific format code syntax.", + "missing_concepts": [ + "datetime.strptime() method for parsing strings", + "datetime.strftime() method for formatting dates", + "Datetime format codes (%d, %m, %Y)", + "timedelta(days=...) constructor syntax" + ], + "proposed_fix": "Add a reference snippet that explicitly defines strptime/strftime and lists common format codes for days, months, and years." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Datetime Formatting Reference' snippet: 'Use datetime.strptime(text, format) to read a date, and date.strftime(format) to write it. Format codes: %d=day, %m=month, %Y=year (e.g., \"%d-%m\" -> \"02-05\"). timedelta(days=n) adds or subtracts n days.'", + "why_helpful": "It provides the exact translation key needed to interpret the input string and construct the output string.", + "why_maybe_unnecessary": "While Python-specific, some students might guess %m=month and %d=day, but it is risky without confirmation.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:54:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q16", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q16", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Easy_3", + "question": "You have the following definition for a class called Shape:\n\nWhat would be the output if we execute the following commands?\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "options": { + "a": "True", + "b": "False", + "c": "An error", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "`Shape(5, 3).area` is `5 * 3 = 15`, and `Shape(1, 15).length` is `15`, so the comparison evaluates to `True`.", + "code_context": "class Shape:\n def __init__(self, height, length):\n self.height = height\n self.length = length\n self.area = self.height * self.length\n\nprint(Shape(5, 3).area == Shape(1, 15).length)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Explains the fundamental structure of a class, the __init__ method, and how attributes (like name and mode) are initialized at the time of object construction, which is the core logic needed to understand the Shape class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the blueprint for understanding class initialization and attribute assignment." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Demonstrates that the '==' operator performs a comparison and returns a boolean value (True/False), which is the final step of the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to access and compare object attributes (like review scores), illustrating the 'object.attribute' syntax used in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Teaches __init__ and attribute setup." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Teaches comparison logic and output types." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Teaches dot-notation for attribute access." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class structure, initialization, and comparison logic. However, a student with zero knowledge might still struggle to trace how 'Shape(5, 3)' maps to 'self.height' and 'self.length' specifically, as the snippets don't explicitly walk through the calculation of a third attribute (area) based on inputs.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main gap is an explicit explanation of how positional arguments in an instantiation call map to the __init__ method's parameters, and how calculated attributes are stored.", + "missing_concepts": [ + "positional argument mapping in __init__", + "calculated attributes vs passed attributes", + "tracing multiple object instances in one expression" + ], + "proposed_fix": "Add a snippet that defines a simple class with a calculated attribute (e.g., Circle with radius and area) and shows the step-by-step trace of creating the object and accessing both attributes." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet titled 'OOP: Calculated Attributes' showing a class Rectangle(width, height) that sets self.area = width * height. It should include a comment: 'Rectangle(2, 5) makes width=2, height=5, and area=10'.", + "why_helpful": "It directly mirrors the logic of the question (Shape with area = height * length), making the trace obvious to a non-programmer.", + "why_maybe_unnecessary": "The 'Vehicle' snippet covers 80% of the logic; the user might be able to 'jump' the remaining gap.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:55:14Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q17", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q17", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "6-string - operations - 2", + "question": "Write a function called shuffle_sentence that takes a string as an argument and returns a new string where the words are shuffled randomly.\n\nFor example, if your function is called as:\nshuffle_sentence(\"Hello, how are you today?\")\nthen it could return a shuffled string like:\n'how today? you Hello, are'\n\nWhich of the following programs work(s) according to the requirements?\n\nHints:\nThe shuffle() function is a method from the random module. The shuffle() method takes a sequence, like a list, and reorganizes the order of the items. This method changes the original list; it does not return a new list.\nThe reversed() function computes the reverse of a given sequence object and returns it in the form of a list.", + "options": { + "a": "def shuffle_sentence(sentence):\n words = sentence.split()\n return ' '.join(reversed(words))", + "b": "import random\n\ndef shuffle_sentence(sentence):\n words = sentence.split()\n random.shuffle(words)\n return ' '.join(words)", + "c": "Both of the programs work.", + "d": "Neither of the programs work." + }, + "correct": "b", + "explanation": "Option B is the only one that actually shuffles the words randomly. Option A only reverses the word order, which does not satisfy the random-shuffle requirement.", + "code_context": "shuffle_sentence(\"Hello, how are you today?\")\n# could return: 'how today? you Hello, are'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "Explicitly teaches the concept of in-place mutation ('Check whether the method mutates the list in place'), which is critical for understanding why random.shuffle(words) is called on its own line in the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Focuses on method mutation, helping the student understand the 'random.shuffle' hint provided in the question." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the 'reverse()' method, providing a helpful contrast to the 'reversed()' function mentioned in the question's hints." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Explains that strings are immutable and methods like .replace() return new strings, helping students differentiate between string methods and list mutations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Covers mutation vs returning new objects." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Covers method vs function syntax (reverse vs reversed)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Covers string immutability." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The question hints explain 'shuffle' and 'reversed' behavior, and 'aiq-2' reinforces the mutation concept. However, none of the snippets explicitly explain '.split()' or '.join()', which are the two primary mechanisms for converting between the input string and the list required for shuffling.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main missing link is the 'String-to-List' and 'List-to-String' transformation syntax.", + "missing_concepts": [ + "str.split() method for creating word lists", + "' '.join(list) syntax for reconstructing sentences" + ], + "proposed_fix": "Add a snippet or edit an existing string operation snippet to show a round-trip transformation (split and join)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Sentence Reconstruction. Content: 'To turn a sentence into a list of words, use sentence.split(). To turn a list of words back into a sentence with spaces, use \" \".join(words_list).'", + "why_helpful": "This directly provides the syntax for the only two parts of the code not explained by the question's internal hints.", + "why_maybe_unnecessary": "A student might infer split/join from the context of the options, but it's a high cognitive load for zero-knowledge users.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:55:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q18", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q18", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "6-strings - find & replace - 1", + "question": "Consider the following line of code:\n\ntext = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\n\nYou want to create a new string called new_text where all occurances of \"oil\" are replaced by \"natural gas\".\n\nSo:\nprint(new_text)\nshould return:\n\"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "new_text = ' '.join([word if word != 'oil' else 'natural gas' for word in text.split()])", + "b": "new_text = text.replace(\"oil\", \"natural gas\")", + "c": "new_text = text.split()\nfor index, word in enumerate(new_text):\n if word == 'oil':\n new_text[index] = 'natural gas'\nnew_text = ' '.join(new_text)", + "d": "All of the given options works as intended." + }, + "correct": "d", + "explanation": "All three code fragments replace each occurrence of the standalone word `oil` with `natural gas`, so the correct answer is that all of them achieve the requested result.", + "code_context": "text = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\nprint(new_text)\n# should return:\n# \"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions processing strings where characters are separated by specific delimiters (dashes), which is the most related context for string cleaning/manipulation, even though the specific methods like .replace() aren't shown." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Relates to the core task of identifying and modifying specific characters or patterns within a string (phone numbers with separators)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Discusses extracting components from a string (URL TLD), which implicitly requires string partitioning or splitting logic similar to options A and C." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates string slicing and the 'list()' function, which helps a student understand that strings can be treated as sequences or converted to lists (relevant to Option C)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Context for string manipulation." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Context for string splitting." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Context for string-to-list behavior." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Mentions having a 'list of strings called words', which mirrors the output of 'text.split()' used in the question." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets explicitly mention or demonstrate the '.replace()', '.split()', or '.join()' methods. A student with zero prior knowledge would have no way to verify if 'text.replace(\"oil\", \"natural gas\")' is valid Python syntax or if it correctly handles all occurrences. The logic of list comprehensions (Option A) is also completely absent from the candidates.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate list is missing foundational string methods and sequence joining documentation.", + "missing_concepts": [ + "str.replace()", + "str.split()", + "str.join()", + "List comprehension with inline if-else" + ], + "proposed_fix": "Add a documentation snippet or a lecture card from Week 1 or Week 4 that specifically lists and examples 'String Methods for Search and Replace'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a card for 'Essential String Methods' covering split(), join(), and replace().", + "why_helpful": "This would provide the direct definitions needed for all three code segments (a, b, and c) in the question.", + "why_maybe_unnecessary": "Only unnecessary if the user assumes the student can guess method names based on English meaning.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:56:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q19", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q19", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - hard - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Select all rows where the age is greater than 30 and the gender is \"Male\".\n- Operation 2: Create a new column called Sex_abbr of which the values should be \"F\" if gender is \"Female\" and \"M\" if gender is \"Male\".\n- Operation 3: Calculate the average salary of all employees.\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df_operation1 = df[(df['Age'] > 30) & (df['Gender'] == 'Male')]\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "b": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "c": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = df['Gender'].map(lambda x: 'M' if x == 'Male' else 'F')\ndf_operation3 = df['Salary'].sum()/len(df)", + "d": "df_operation1 = df[df['Age'] > 30 & df['Gender'] == 'Male']\ndf['Sex_abbr'].map(lambda x: 'M' if x == 'Male' else 'F' for x in df['Gender'])\ndf_operation3 = df['Salary'].sum()/len(df)" + }, + "correct": "a", + "explanation": "Option A correctly filters rows with both conditions using boolean masking, builds the abbreviation column from the Gender column, and computes the average salary with mean().", + "code_context": "Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Introduces the concept of a 'boolean mask' to select rows, which is the foundational logic needed for Operation 1." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Explains boolean masking for filtering rows, relevant to Operation 1." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions the .mean() method, which is the direct solution for Operation 3 (average salary)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates how to create a new column in a DataFrame by assigning values to a new key (df['C'] = ...), relevant to Operation 2." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Covers boolean selection/masking." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides the .mean() method." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic column assignment syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions the .map() method, which helps a student evaluate options C and D, even if option A uses a list comprehension." + } + ], + "answerability": { + "status": "partial", + "confidence": "low", + "rationale": "The snippets cover individual components: row filtering (masking), column creation, and the .mean() method. However, they do not demonstrate how to combine multiple conditions using '&' (crucial for Op 1) nor do they show the specific list comprehension syntax for conditional value assignment (crucial for Op 2). A student with zero Python knowledge might struggle to synthesize these complex pandas-specific syntax rules.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets lack examples of multi-condition boolean indexing and inline conditional logic (list comprehensions) applied to DataFrame columns.", + "missing_concepts": [ + "Multi-condition boolean filtering with the & operator in Pandas", + "List comprehension for conditional column assignment (if-else inside a list)", + "Distinction between .loc() and [] for filtering" + ], + "proposed_fix": "Add a snippet or exam question that explicitly uses '&' to filter a DataFrame and assigns a new column based on a list comprehension with internal if-else logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: df_filtered = df[(df['A'] > 5) & (df['B'] == 'Yes')] and df['New'] = ['High' if x > 10 else 'Low' for x in df['A']]", + "why_helpful": "This would directly illustrate the two most complex parts of the question: combining boolean filters and using list comprehensions for data transformation.", + "why_maybe_unnecessary": "The student might infer masking from the single-condition example, though the '&' operator is a specific technical hurdle.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:56:27Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q20", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q20", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - lambda - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000\n\nYou want to create a new column called Bonus that compute each employee's bonus based on their salary and performance review using the following formula:\n- if the performance review is less than 4, the bonus is 0.\n- if the performance review is 4 or 5, the bonus is 5% of the salary.\n\nWhich of the following code snippets works as intended?", + "options": { + "a": "df['Bonus'] = df.apply(lambda row: row['Salary']*0.05 if row['Performance_review']>=4 else 0, axis=1)", + "b": "df['Bonus'] = df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>=4 else 0)", + "c": "df['Bonus'] = map(df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>4 else 0))", + "d": "df['Bonus'] = df['Salary'].map(lambda row: row*0.05 if df['Performance_review']>=4 else 0)" + }, + "correct": "a", + "explanation": "Option A evaluates each row, checks the row's Performance_review value, and returns either 5% of Salary or 0 for that employee.", + "code_context": "Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column ('C') from existing columns ('A' and 'B') in a pandas DataFrame, which matches the target question's structure for creating a 'Bonus' column." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates DataFrame column creation/assignment syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that methods like .map() allow applying functions to values, providing the conceptual bridge to .apply() and .map() used in the options." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Introduces the concept of 'applying functions' to multiple elements, which is the core logic of the .apply() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "RHS/LHS assignment for columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Usage of mapping functions." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain 'lambda' syntax, 'if/else' logic within a function call, or the crucial 'axis=1' parameter required for row-wise DataFrame operations. A student without prior knowledge wouldn't understand why Option A is superior to B or D.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets cover basic column assignment and the concept of mapping, but fail to explain higher-order function syntax (lambda) and row-wise DataFrame processing.", + "missing_concepts": [ + "lambda function syntax", + "df.apply(..., axis=1) for multi-column row logic", + "inline if-else (ternary) operators in Python" + ], + "proposed_fix": "Add a snippet or AI-generated section specifically illustrating row-wise calculations in Pandas using .apply(lambda row: ..., axis=1) with a simple conditional." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Row-wise Calculations with Lambda. Content: To create a column based on multiple other columns, use df.apply(lambda row: expression, axis=1). For example: df['Total'] = df.apply(lambda r: r['A'] + r['B'] if r['C'] > 0 else 0, axis=1).", + "why_helpful": "This directly maps to the correct answer's pattern, explaining both the multi-column access (row['Col']) and the conditional logic.", + "why_maybe_unnecessary": "If the student is expected to infer lambda from general function application, but that is unlikely for a 'zero knowledge' persona.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:56:53Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q21", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q21", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_3", + "question": "You want to create a function called main which take an integer and a flexible number of strings as arguments. The strings represent dates in the format of DD MM YYYY. The day, month and year can be separated by different characters.\n\nYour function should look for the string inputs which represent dates as DD-MM-YYYY or DD/MM/YYYY and return those strings in the format of DD.MM.YYYY in a list. Furthermore, the dates represented by the strings should be shifted by the amount of days as given by the integer argument.\n\nFor example, if we call your function as:\nmain(3, '25/06/2003', '26.06.2003', '27-06-2003', '28:06:2023', '29-06-2023', '30.06.2023')\n\nthe output should be:\n['28.06.2003', '30.06.2003', '02.07.2023']\n\nTake a look at the following code segment. Does it do what is intended? If not, then why not?", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the function will return a list of datetime objects, not a list of strings representing dates.", + "c": "This code segment does not work because the strftime() method cannot be applied to NoneType object.", + "d": "This code segment produces an error because you cannot concatenate strings and timedelta." + }, + "correct": "b", + "explanation": "The function parses matching inputs and adds the day offset, but it appends datetime objects and never converts them back to strings in DD.MM.YYYY format before returning.", + "code_context": "def main(delta, *args):\n dates = []\n for string in args:\n if '-' in string:\n dates.append(datetime.strptime(string, '%d-%m-%Y') + timedelta(days=delta))\n elif '/' in string:\n dates.append(datetime.strptime(string, '%d/%m/%Y') + timedelta(days=delta))\n else:\n dates.append(None)\n return [date for date in dates if type(date) != None]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that demonstrates the use of a flexible number of arguments (*args) and discusses function definitions working 'as intended', which matches the structure and syntax of the exam question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains flexible arguments (*args), which is central to the function signature provided in the code context." + }, + { + "item_id": "aiq-4", + "rationale": "Provides an example of a function taking a flexible number of arguments and discusses return types, which is relevant to the correct answer (b)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Focuses on formatting strings as output from functions, providing a conceptual link to the 'intended' vs 'actual' string formatting failure in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers the *args syntax used in the question." + }, + { + "item_id": "aiq-4", + "rationale": "Reinforces flexible argument handling and return behavior." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the available snippets mention the datetime library, strptime, timedelta, or the difference between a datetime object and a formatted string. A student with zero Python knowledge would have no way to know that datetime.strptime returns an object rather than a string, or how to distinguish between the two types in the context of option (b).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets only cover function signatures (args/kwargs) but completely lack technical documentation for the datetime module which is the core subject of the question.", + "missing_concepts": [ + "datetime.strptime return type", + "datetime.strftime for string conversion", + "timedelta for date arithmetic", + "The difference between an object type and a string representation" + ], + "proposed_fix": "Add a dedicated snippet explaining the Datetime module, specifically showing that strptime creates objects and strftime creates strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Working with Datetimes. Content: Use `datetime.strptime(date_string, format)` to convert a string to a datetime OBJECT. Use `dt_object.strftime(format)` to convert it back to a STRING. Use `timedelta(days=n)` to add/subtract days from a datetime object.", + "why_helpful": "This provides the missing technical knowledge required to understand why the code returns objects (Option B) instead of the desired strings.", + "why_maybe_unnecessary": "The topic might be covered in later weeks, but since the question is about Datetime Function 3, it's essential for this specific task.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:57:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q22", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q22", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_2", + "question": "You want to define a class called Calendar, which has four attributes that are initialized at the time of object construction:\n1. The 'event' attribute can be any string,\n2. The 'date' attribute is a string representing a date as 'DD-MM-YYYY',\n3. The 'start' attribute is a string representing the time as 'HH:MM', and\n4. The 'length' attribute is an integer representing the amount of minutes.\n\nThe class should also have a method called get_details() that gives a description of Calendar objects.\n\nFor example, if we execute the following commands;\nevent1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n\nthe output should be:\nCoffee meeting: 01-06-2023, 9:30-9:50.\n\nWhich of the following code segments gives you what you want?", + "options": { + "a": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day, int(start.split(':')[0]), int(start.split(':')[1]))\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "b": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.split(':')[0], minute=start.split(':')[1])\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "c": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.hour, minute=start.minute)\n self.end = self.self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "d": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start.hour = start.hour\n self.start.minute = start.minute\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'" + }, + "correct": "a", + "explanation": "Option A is the only choice that correctly parses the date string, combines the parsed date with the split start time to build a datetime, adds the duration in minutes, and formats the requested details string.", + "code_context": "event1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n# output:\n# Coffee meeting: 01-06-2023, 9:30-9:50." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-format", + "rationale": "This snippet provides the essential syntax for datetime construction, strftime formatting, and explicitly mentions strptime and timedelta, which are the core components needed to solve the datetime logic in Option A." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-format", + "rationale": "Covers datetime parsing, formatting, and object creation, which are the primary technical hurdles in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows the standard boilerplate for defining a class with an __init__ method and multiple attributes, which is the required structure for the Calendar class." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Introduces the concept of timedelta objects, helping the student identify that time arithmetic (like adding minutes) requires this specific class." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-format", + "rationale": "Provides datetime parsing/formatting logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides class and constructor structure." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Contextualizes timedelta for time calculations." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates f-string interpolation which is used in the get_details() method return statement." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The available snippets cover class structure and basic datetime formatting (strftime/strptime). However, the specific logic of using .split(':') to parse a time string and the exact syntax for adding minutes via timedelta(minutes=...) are not explicitly demonstrated, making the 'Hard' part of the question difficult for a zero-knowledge student.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the high-level components (Classes, Datetime) but lack the connective tissue for string manipulation and specific timedelta parameter usage.", + "missing_concepts": [ + "string.split() for parsing time", + "timedelta(minutes=...) parameter usage", + "accessing attributes from another object (self.date.year, etc.)" + ], + "proposed_fix": "Add a new example snippet that demonstrates parsing a string like 'HH:MM' into a datetime object using split and performing minute-based arithmetic with timedelta." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Parsing Time Strings and Minute Arithmetic\nfrom datetime import datetime, timedelta\nstart_str = '9:30'\nh, m = start_str.split(':')\nstart_dt = datetime(2023, 6, 1, int(h), int(m))\nend_dt = start_dt + timedelta(minutes=20)\nprint(f'End: {end_dt.strftime(\"%H:%M\")}')", + "why_helpful": "This directly models the logic required in the __init__ method of the question, specifically the combination of string splitting, int conversion, and timedelta usage.", + "why_maybe_unnecessary": "A student might guess split() based on common sense, but the timedelta(minutes=...) syntax is hard to intuit without an example.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:57:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q23", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q23", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Function_2", + "question": "You have the following definition for a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nYou want to add three methods to this class:\n1. The holiday_bonus() method which computes and returns the holiday bonus, which is 8.0% of the yearly salary,\n2. The year_end_bonus() method which computes and returns the year end bonus, which is 8.3% of the yearly salary\n3. The payment_overview() method which returns a payment overview of the employee using the following format:\n[Name] receives $[salary] monthly, $[holiday bonus] in May and $[year end bonus] in December.\n\nFor example, if we execute the following commands:\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())\n\nthe output should be:\n2400.0\n2490.0\nJohn Smith receives $2500 monthly, $2400.0 in May and $2490.0 in December.\n\nWhich of the following code segments should you place on the blank in the class definition to achieve what you want?", + "options": { + "a": "def holiday_bonus(self):\n return self.salary * 12 * 0.080\ndef year_end_bonus(self):\n return self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus()} in May and ${self.year_end_bonus()} in December.'", + "b": "def payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.salary*12*0.08} in May and ${self.salary*12*0.083} in December.'", + "c": "def holiday_bonus():\n self.holiday_bonus = self.salary * 12 * 0.080\ndef year_end_bonus():\n self.year_end_bonus = self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'", + "d": "def payment_overview(self):\n self.holiday_bonus = self.salary * 12 * 0.080\n self.year_end_bonus = self.salary * 12 * 0.083\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'" + }, + "correct": "a", + "explanation": "Option A defines all three requested methods, computes the two bonuses from the yearly salary, and uses those method results in the overview string.", + "code_context": "class Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "It introduces the concept of defining a custom method within a class to perform logic based on object attributes, which is the primary requirement for solving the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Provides the conceptual framework for adding functional methods (like 'compare') to a class." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows basic class definition syntax and attribute initialization using 'self', which helps a student understand the 'self.attribute' references in the options." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string formatting with placeholders (e.g., [NAME]), which is helpful for identifying the correct format of the payment_overview return string." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Conceptual method definition." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Standard class/self syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "String interpolation pattern." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the selected snippets explain class structure and basic string formatting, they do not demonstrate two critical Python OOP requirements: 1) that 'self' must be the first parameter in a method definition, and 2) that calling an internal method requires the 'self.method_name()' syntax. Without these, a student cannot confidently choose (a) over (c) or (d).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets cover 'what' to do (define methods) but not the 'how' (the specific syntax of self and internal method calls).", + "missing_concepts": [ + "Mandatory 'self' parameter in instance method definitions", + "Accessing instance methods via 'self.method_name()'", + "Calling methods within f-strings" + ], + "proposed_fix": "Add a snippet showing a class where one method calls another method using 'self', specifically demonstrating the use of parentheses for the call." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for a 'Circle' class that has a 'radius' attribute, an 'area(self)' method, and a 'summary(self)' method that returns f'Area is {self.area()}'.", + "why_helpful": "This would explicitly teach the student that methods need 'self' as an argument and 'self.' prefix with parentheses to be called, directly addressing the distractors in options C and D.", + "why_maybe_unnecessary": "It is a fundamental OOP concept, but 'zero knowledge' students require an explicit code example of method-to-method calling.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:58:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q24", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q24", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Hard_2", + "question": "You have the following definitions for a class called Car:\n\nclass Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nYou want to create another class called Garage, which has two attributes that are initialized during object construction:\n- The 'capacity' attribute, which is an integer and must be passed to the object constructor.\n- The 'cars' attribute, which is an empty list.\n\nThe Garage class should also have two methods:\n1. The add_car() method, which adds Car objects to a Garage object. New Car objects can only be added if there is still capacity in the Garage object. If not, the method should return \"Capacity reached.\"\n2. The check_garage() method, which reports the Car objects that have been added to the Garage object. The method should return a dictionary in which the keys are the counts of Car objects starting from 1 and the values are the Car objects' descriptions.\n\nFor example, if we execute the following commands:\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n\nthe output should be:\n{1: 'Toyota, Camry', 2: 'Honda, Accord'}\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "class Garage:\n def __init__(self, capacity, cars = []):\n self.capacity = capacity\n\n def add_car(self, car):\n self.cars += car if len(self.cars) < self.capacity else return 'Capacity reached.'\n\n def check_garage(self, car):\n return {index: car.get_description() for index, car in enumerate(self.cars, start=1)}", + "b": "class Garage:\n def __init__(self, capacity):\n self.capacity = capacity\n self.cars = []\n\n def add_car(self, car):\n if len(self.cars) < self.capacity:\n self.cars.append(car)\n else:\n return 'Capacity reached.'\n\n def check_garage(self):\n output = {}\n for index, car in enumerate(self.cars, start=1):\n output[index] = car.get_description()\n return output", + "c": "Both of the above will work.", + "d": "None of the above will work." + }, + "correct": "b", + "explanation": "Option B initializes capacity and an empty cars list, appends cars only when capacity remains, returns the required message when full, and builds the requested dictionary in check_garage().", + "code_context": "class Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n# output:\n# {1: 'Toyota, Camry', 2: 'Honda, Accord'}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows the basic structure of a Python class definition and the __init__ method for attribute initialization, which is central to the Garage class requirements." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides a template for defining a class and initializing multiple attributes, including those passed to the constructor." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the specific dictionary output format {1: 'I', 2: 'II'} requested in the check_garage method, helping the student recognize the target structure." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Illustrates the logic of mapping list elements to dictionary keys, which is required for the check_garage method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Class/Init structure." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Target dictionary output pattern matching." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Basic dictionary creation logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the 'outer shell' (Class definition, attribute initialization, and dictionary output format). However, they do not explain the behavior of 'list.append()' vs 'list += object' or the specific 'enumerate(..., start=1)' syntax, which are necessary to distinguish between options A and B.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student lacks information on how to add an item to a list attribute and how to use enumeration to generate sequential keys in a dictionary.", + "missing_concepts": [ + "list.append() method", + "enumerate(list, start=1) syntax", + "Default mutable argument trap (Option A uses cars=[])", + "Difference between list += item and list.append(item)" + ], + "proposed_fix": "Add a snippet demonstrating a class that manages a list of items, showing how to append to the list and how to iterate through it using enumerate to produce a dictionary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet (e.g., 'OOP Method with List and Enumerate') that shows a class 'Inventory' with an 'items' list, an 'add_item' method using '.append()', and a 'get_indexed_items' method returning a dictionary using 'enumerate(self.items, start=1)'.", + "why_helpful": "Directly demonstrates the mechanics needed to solve '9_OOP_Hard_2', specifically list mutation and dictionary generation with custom start indices.", + "why_maybe_unnecessary": "If the student already understands list basics from a separate 'Lists' section, this might be redundant, but for zero-knowledge students, this bridge is vital.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:58:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q01", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q01", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_3", + "question": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?", + "options": { + "a": "if x in list(range(11))[::2]:\n print('Even number')\nelse:\n print('Odd number')", + "b": "if x % 2 != 0:\n print('Odd number')\nelse:\n print('Even number')", + "c": "if x in [1, 3, 5, 7, 9]:\n print('Odd number')\nelse:\n print('Even number')", + "d": "All of the programs work as intended." + }, + "correct": "d", + "explanation": "Option A checks membership in the even numbers from 0 through 10, option B checks oddness with modulo, and option C checks membership in the odd numbers from 1 through 9. All three correctly classify x as odd or even in the stated range.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive). Which of the following programs will tell you whether x contains an odd or eve", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-1-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-1-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "This snippet is a verbatim copy of the same question from a previous exam year and explicitly states that 'All three programs correctly identify whether x is odd or even', pointing directly to the correct answer (d)." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Directly contains the identical question, answer key, and logic explanation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates slicing syntax [1::2] on a list, which helps a student understand how the slicing [::2] in Option A functions." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Mentions filtering and summing even integers, providing a conceptual link to parity (even/odd) logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "This snippet alone provides the exact solution and reasoning for the specific problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of a verbatim match from a trial exam makes the question answerable without any understanding of the underlying Python code, as the student can simply match the text and see the stated answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the verbatim match exists, there is a total lack of conceptual documentation for the modulo operator (%) and the range() function, which are critical for actually understanding the options.", + "missing_concepts": [ + "Modulo operator (%) for checking parity (even/odd)", + "range(n) function behavior", + "Step slicing syntax [::step]" + ], + "proposed_fix": "Add a foundational snippet explaining basic Python arithmetic (specifically modulo) and how range(n) creates sequences of numbers." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Arithmetic and Logic Basics: Explain that 'x % 2 == 0' checks if a number is even (no remainder) and 'x % 2 != 0' checks if it is odd. Explain that range(11) creates numbers 0 to 10.", + "why_helpful": "This allows the student to verify Option B and Option A independently rather than relying on a verbatim question match.", + "why_maybe_unnecessary": "If the goal is purely 'cheating' by pattern matching, the existing verbatim snippet is sufficient.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:59:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q02", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q02", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_2", + "question": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "options": { + "a": "This code will produce an error because a is a global name that is referenced inside the local scope of inner().", + "b": "This code will not produce any error and will return 30.", + "c": "This code will produce an error because c is not defined before referencing.", + "d": "This code will not produce any error and will return 50." + }, + "correct": "b", + "explanation": "The function inner receives c as its argument, so c is defined. It can also read the global a. inner(5) returns 1 + 5 + 4 = 10, and outer returns 10 * 3 = 30.", + "code_context": "a = 1\ndef outer(b):\n b = 3\n def inner(c):\n d = 4\n return a + c + d\n return inner(5) * b\nouter(5)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "rationale": "This is an exact match for the question, providing the full trace and mathematical calculation (10 * 3 = 30) that confirms why there is no error." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "rationale": "Directly answers the specific question and code provided." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the underlying rules: global names are known everywhere except where a local name dominates, justifying why 'a' is accessible inside 'inner'." + }, + { + "item_id": "manual-unboundlocal", + "rationale": "Explains that assignment makes a name local, which helps understand why 'b' in outer(5) becomes 3 and stays local to outer." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "rationale": "Contains the specific solution." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the general logic for global/local name access." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact exam question and its explanation, as well as the fundamental lecture theory on scope rules.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact answer is present, there is no explicit mention of 'Enclosing Scope' or 'Nested Functions' in the theory snippets, which might confuse a total beginner seeing a function inside a function for the first time.", + "missing_concepts": [ + "Nested function definitions", + "Enclosing (non-local) scope" + ], + "proposed_fix": "Add a conceptual snippet explaining that functions can be defined inside other functions and can access variables from the outer function's scope." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Nested Functions and Enclosing Scope. Content: Python allows defining a function (inner) inside another function (outer). The inner function can access variables defined in the outer function (its enclosing scope) as well as global variables. Example: def outer(x): y=10; def inner(z): return x+y+z; return inner.", + "why_helpful": "It explains the structure of the code context, which involves nested functions—a concept not explicitly covered in the 'Global vs Local' snippet.", + "why_maybe_unnecessary": "A student might simply follow the trace in the existing exam-match snippet without needing the formal definition of nested scopes.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:59:26Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q03", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q03", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_2", + "question": "What will be returned by the following code segment?", + "options": { + "a": "[0, None, 2, 3, None, 5, 6, 7, 8, None]", + "b": "[0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, 9]", + "c": "[None, 1.0, None, None, 3.5, None, None, None, None, '9']", + "d": "[0, None, 2, 3, None, 5, 6, 7, 8, 9]" + }, + "correct": "a", + "explanation": "The function appends each item if its exact type is int; otherwise it appends None. In the given list, 1.0, 3.50, and '9' are not ints, so those positions become None.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n if type(item) == int:\n list_2.append(item)\n else:\n list_2.append(None)\n return list_2\n\nmain([0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, '9'])" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What will be returned by the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ], + "evidence_topics": [ + "Return Behavior" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "This snippet explicitly explains the exact logic of the question: that 1.0 and 3.50 are floats and '9' is a string, so they do not match the 'int' type check and are replaced by None." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Provides the direct explanation for why floats and strings are excluded in a type-check for integers." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Clearly labels different Python types (str, int, float, etc.), helping a student identify that 1.0 is a float and '9' is a string." + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Shows a similar code structure using a loop and a type comparison (type(i) == type(x)) to build a new list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Directly explains the logic and the specific values in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet is a near-perfect match for the question's logic and explanation, making the answer obvious even without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective because one of them appears to be a direct explanation of this specific exam question or a very similar variant.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:59:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q04", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q04", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 2", + "question": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}", + "b": "roman_nums = {roman: num for roman, num in zip(['I', 'II', 'III', 'IV', 'V'], range(1, 6))}", + "c": "roman_nums = {num: ['I', 'II', 'III', 'IV', 'V'][num] for num in range(1, 6)}", + "d": "roman_nums = {num: roman for num, roman in zip(range(1, 6), 'I II III IV V')}" + }, + "correct": "a", + "explanation": "Option A zips the integers 1 through 5 with the five Roman numeral strings and builds the required dictionary. The other options either reverse the keys and values, use incorrect indexing, or iterate over a plain string instead of the intended list of numerals.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols. Tha", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet explicitly mentions creating a dictionary from a list where keys are strings and values are lengths, which typically uses the dictionary comprehension syntax {k: v for ...} required for the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides the conceptual pattern for dictionary comprehension (mapping keys to values in a new dict)." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Introduces the use of 'zip' with names and ages to create a dictionary, which is the specific mechanism used in the correct answer (Option A)." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While it is a duplicate of the question, having the problem statement on the sheet helps a student recognize the task, though it lacks the implementation details in its current truncated form." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows that dictionary creation often involves iterating over a collection to map keys to values." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Explicitly connects 'zip' with dictionary creation from two lists." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the 'zip' concept and the 'dictionary comprehension' concept separately. A student would need to infer that they can be combined into '{k: v for k, v in zip(...)}'. No single snippet shows the combined syntax clearly enough for someone with zero Python knowledge to be certain.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no snippet that demonstrates the specific syntax of a dictionary comprehension using zip: {key: value for key, value in zip(list1, list2)}.", + "missing_concepts": [ + "dictionary comprehension syntax with zip", + "range(start, end) behavior (inclusive/exclusive)" + ], + "proposed_fix": "Add or modify a snippet to show a complete, valid dictionary comprehension example that uses zip() on a range and a list." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "proposal": "Update the search_text/content to include the correct code segment: 'roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}'.", + "why_helpful": "It provides the direct answer and the exact syntax for the comprehension + zip pattern.", + "why_maybe_unnecessary": "If the goal is to teach the principle rather than give the answer, a generic zip-comprehension example might be better.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a summary snippet for 'Dictionary Comprehensions' showing: {k: v for k, v in zip(keys, values)} and explaining that range(1, 6) produces 1, 2, 3, 4, 5.", + "why_helpful": "It bridges the gap between the individual components (zip and comprehension) and explains the range function logic.", + "why_maybe_unnecessary": "None; this is a core missing piece for zero-knowledge users.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:00Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q05", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q05", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 2", + "question": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to only include the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[name] = age", + "b": "person_dict = {}\nfor i, name in enumerate(names):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[i] = ages[i]", + "c": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict.append(name:age)", + "d": "person_dict = {}\nfor i, name in enumerate(names):\n for j, letter in enumerate(name):\n if letter == 'A' or letter == 'C':\n person_dict[i] = ages[j]" + }, + "correct": "a", + "explanation": "Option A correctly iterates over names and ages together and stores only the names beginning with A or C as keys mapped to their ages. The other options use indices as keys, invalid dictionary syntax, or incorrect nested-loop logic.", + "code_context": "names = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have two lists representing the names and ages of individuals: names = ['Alice', 'Bob', 'Charlie', 'David'] ages = [25, 30, 35, 40] You need to create a dictionary called perso", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This snippet is an exact match for the exam question provided, containing the same scenario, variable names (names, ages), and requirements." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Directly matches the question context and logic requirements." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the standard syntax for creating a dictionary from a list (keys) and mapping them to values (lengths), which reinforces the dict[key] = value pattern used in the correct answer." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Shows conditional logic within a loop to update a dictionary (if letter in counts), which helps a student understand the structure of the correct option's loop." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides the specific problem context and likely the options or solution pattern." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Validates the dictionary assignment syntax needed to distinguish Option A from Option C (which uses an invalid .append() method)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the source version of the exact same question. Even if they didn't, other snippets demonstrate dictionary assignment syntax and looping, which are the core concepts needed.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main technical hurdle is understanding 'zip()' and string indexing 'name[0]'. While 'name[0]' is somewhat intuitive, 'zip()' is a specific Python function not explicitly defined in the other dictionary snippets.", + "missing_concepts": [ + "zip() function functionality", + "String indexing for first character (name[0])" + ], + "proposed_fix": "Add a snippet or detail rule explaining how zip() combines two lists into pairs for iteration." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Syntax' card for the 'zip()' function that shows: for x, y in zip(list1, list2): ...", + "why_helpful": "It clarifies how the loop in the correct answer manages to access both 'name' and 'age' simultaneously without using an index variable.", + "why_maybe_unnecessary": "The student might infer the behavior from the context of the question/answer pair, but a definition ensures certainty.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q06", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q06", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 2", + "question": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?", + "options": { + "a": "max_rating = max(employee_ratings.values())\nfor employee, rating in employee_ratings.items():\n if rating == max_rating:\n print(employee)", + "b": "max_rating_employee = max(employee_ratings.keys())\nfor employee, rating in employee_ratings.items():\n if employee == max_rating_employee:\n print(employee)", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "a", + "explanation": "Option A correctly computes the maximum rating value and prints every employee whose rating matches it. Option B instead finds the maximum key lexicographically, not the employee with the highest rating.", + "code_context": "employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You have the following dictionary that represents the performance ratings of employees in a company: employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text and context, providing the most direct path to the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Exact match for the exam question being asked." + }, + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the pattern of iterating through a dictionary (math_scores) to find names based on a value-derived condition." + }, + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "rationale": "Discusses finding highest and lowest values within dictionaries, which reinforces the concept of max/min operations on dictionary values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Contains the specific scenario and logic required." + }, + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Provides a secondary example of filtering dictionary keys (names) by their associated values (scores)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the exact question being evaluated. A student can simply identify the matching problem description to find the solution.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact question is present, there is a lack of a general 'rule' snippet that explicitly explains the difference between max(dict) (keys) and max(dict.values()).", + "missing_concepts": [ + "Explicit comparison between max(dict.keys()) and max(dict.values())", + "Explanation of .items() unpacking in a for-loop" + ], + "proposed_fix": "Add a summary card or 'Cheat Sheet Rule' that clarifies how to find the 'Key with the Maximum Value' versus the 'Maximum Key'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Max/Min Patterns' reference card. Example: To find the key with highest value, use max_val = max(d.values()) then loop if val == max_val. To find highest key alphabetically, use max(d).", + "why_helpful": "This helps a student solve variants of the question (e.g., finding the lowest rating) without relying on seeing the exact problem beforehand.", + "why_maybe_unnecessary": "The student already has the exact answer in the existing exam snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q07", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q07", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[2, 4]", + "b": "[3, 4, 5]", + "c": "[4]", + "d": "[]" + }, + "correct": "c", + "explanation": "The list comprehension keeps values x from [1, 2, 3, 4, 5] only when x is even and greater than 2. The only value satisfying both conditions is 4.", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x for x in numbers if x % 2 == 0 and x > 2]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 7, + "question_summary": "What is the output of the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet contains the exact logic and explanation for the question, explicitly defining that 'x % 2 == 0' checks for even numbers and 'x > 2' is the second condition, leading to the answer '4'." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Direct match for the question logic and provides a clear linguistic explanation of the code's behavior." + }, + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Reinforces the meaning of the modulo operator (%) for parity checks (i % 2 == 0), which is a key part of the question." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Helps a student understand the logical 'and' operator used to combine the two conditions in the list comprehension." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Independently sufficient as it maps the exact code symbols to their logical meanings (even and greater than 2)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The dataset contains an identical question/explanation pair that removes all ambiguity for a non-technical user.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide perfect coverage because of the exact match. There is no need for further concept explanation as the direct answer is present.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:55Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q08", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q08", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "['a', 'bb', 'ccc']", + "b": "[1, 2, 3]", + "c": "[1, 'b', 3]", + "d": "['aa', 'bb', 'cc']" + }, + "correct": "a", + "explanation": "The loop iterates over pairs from zip(list1, list2) and multiplies each string by its matching integer, producing 'a', 'bb', and 'ccc'.", + "code_context": "list1 = [1, 2, 3]\nlist2 = ['a', 'b', 'c']\nresult = []\nfor item in zip(list1, list2):\n result.append(item[0] * item[1])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Demonstrates the basic structure of initializing an empty list, iterating through a collection with a for loop, and using .append() to build the result." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Shows the pattern of iterating over a list and appending results to a new list, which matches the code context structure." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Provides a basic example of the .append() method and list manipulation." + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Reinforces the concept of iterating through a list and appending specific elements to another list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Explains the loop and append logic." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Confirms the behavior of the append method." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While 'append' and 'for loops' are covered, no snippet explains the 'zip()' function or the behavior of multiplying a string by an integer ('a' * 1), which are the critical operations needed to determine the output.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current selection fails to explain Python-specific built-ins and operator overloading used in the question.", + "missing_concepts": [ + "zip() function behavior (pairing elements)", + "String multiplication by integer (repetition)", + "Tuple indexing (item[0], item[1])" + ], + "proposed_fix": "Add an AI-generated or source-exam snippet that demonstrates zip() pairing two lists and shows string-integer multiplication." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'The zip(a, b) function creates pairs of elements from two lists. item[0] refers to the first element in the pair, and item[1] to the second. Multiplying a string by an integer (e.g., \"a\" * 3) repeats the string that many times (\"aaa\").'", + "why_helpful": "Directly addresses the two most obscure parts of the question for a beginner: zip and string multiplication.", + "why_maybe_unnecessary": "Only if the student is expected to guess that 'multiplication' of a string and number behaves like repetition.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:01:12Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q09", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q09", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 1", + "question": "Suppose you have a list called mylist. You want to extract every fourth element starting from index 2 (inclusive) to the second-to-last index (inclusive) of that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45, 50]\n\nthen executing the following command:\nprint(subset)\n\nshould print:\n[20, 35]\n\nWhat should the blanks be filled with?", + "options": { + "a": "2:-1:3", + "b": "2:len(mylist)-1:3", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "c", + "explanation": "Both stop values exclude the last element while starting at index 2 and stepping by 3, so both expressions return [20, 35] for the example list.", + "code_context": "subset = mylist[___:___:___]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "It is the only snippet that explicitly demonstrates the slicing syntax with a step value (alphabet[1::2]), which helps the student recognize the pattern of using colons for slicing." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows basic slicing with a step parameter, though it omits the stop parameter." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Likely involves list manipulation or slicing to reverse/reorder a list, providing additional context for list operations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Establishes the [start:stop:step] syntax pattern." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the snippets explain the crucial rules needed for this question: 1) that the 'stop' index in Python slicing is exclusive (meaning to include the second-to-last item, one must stop at the last item), 2) the index mapping for -1 or len(mylist)-1, and 3) the explicit anatomical breakdown of [start:stop:step].", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets show syntax but not semantics. A student wouldn't know why '2:-1:3' works over other options because the concept of 'exclusive stop' is missing.", + "missing_concepts": [ + "Exclusive stop index in slicing", + "Negative indexing (-1 for last element)", + "Index-to-Position mapping (0-based indexing)" + ], + "proposed_fix": "Add a conceptual snippet or an exam question that explains the [start:stop:step] structure and the exclusive nature of the stop boundary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Slicing Cheatsheet' snippet: 'Python slicing follows the format list[start:stop:step]. Start is inclusive, stop is exclusive. Indices can be negative: -1 is the last element, -2 is second-to-last. Example: mylist[0:5:2] takes every 2nd element from index 0 up to (but not including) index 5.'", + "why_helpful": "This provides the exact mechanical rules required to solve any slicing problem without prior coding experience.", + "why_maybe_unnecessary": "If the goal is only to provide existing exam examples, but those examples currently lack explanatory power for this specific problem.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:01:34Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q10", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q10", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_2", + "question": "Suppose you have the following function, which takes a list of integers as an argument:\n\nWhat will be returned, if we call the function as follows:\nmain([0, 1, 2, 23, 24, 25])", + "options": { + "a": "'abcxyz'", + "b": "['a', 'b', 'c', 'x', 'y', 'z']", + "c": "'012232425'", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "The function walks through the alphabet with enumerate and appends each character whose index is present in the input list, giving a, b, c, x, y, and z.", + "code_context": "def main(x):\n alphabet = 'abcdefghijklmnopqrstuvwxyz'\n y = ''\n for index, character in enumerate(alphabet):\n if index in x:\n y += character\n return y" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "It defines the `alphabet` string variable in a loop context, which provides necessary context for the variable traced in the question, although it lacks the specific `enumerate` logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides the 'abcdefghijklmnopqrstuvwxyz' string definition used in the question." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Shows a function taking a list and iterating over it, which matches the structural pattern of the question's `main([0, 1...])` call." + }, + { + "item_id": "aiq-5", + "rationale": "Explicitly mentions a function taking a 'list of integers as an argument', reinforcing the input type used in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Context for the alphabet string." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Function and loop structure context." + }, + { + "item_id": "aiq-5", + "rationale": "List argument type context." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Provides a visual example of a 'list of integers' which helps a novice identify the input data structure." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The question's solution relies entirely on understanding the `enumerate()` function (which yields index-value pairs) and the `in` membership operator. Neither concept is explained or demonstrated in any of the candidate snippets, making the logic impossible to trace for someone with zero prior Python knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to explain the two core mechanics of the provided code: how `enumerate` works and how `in` checks for list membership.", + "missing_concepts": [ + "enumerate() behavior (index, value pairs)", + "membership operator 'in' for lists", + "string concatenation using +=" + ], + "proposed_fix": "Add a new snippet that specifically illustrates `enumerate()` being used on a string to access both position and character." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Using Enumerate' with code: `for index, char in enumerate('abc'): print(index, char)`. Explanation: 'enumerate' gives the position (0, 1, 2) and the character ('a', 'b', 'c') at the same time.", + "why_helpful": "Directly explains the 'untraceable' part of the question for a beginner.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for the 'in' operator: `if 5 in [1, 5, 10]: # This is True`. Explanation: The 'in' keyword checks if a value exists inside a list.", + "why_helpful": "Explains the conditional logic `if index in x` which determines which letters are appended.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:02:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q11", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q11", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_1", + "question": "Suppose you have a variable called x which contains a string as follows:\n\nx = 'Hello world'\n\nWhich of the following lines of code produce(s) 2 as an output?", + "options": { + "a": "print(x.count('o'))", + "b": "print(x.split(' ')[0].count('ll'))", + "c": "print(len(x)//5)", + "d": "All of the given options." + }, + "correct": "d", + "explanation": "The rendered solution page marks option D, indicating that the exam intends all three listed expressions to produce 2 for the given value of x.", + "code_context": "x = 'Hello world'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", + "rationale": "This snippet explicitly shows the use of 'string.count(letter)', which is essential for evaluating Option A and Option B in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", + "rationale": "Directly demonstrates the '.count()' method used on strings." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions the '.split()' method, which is necessary to understand how the string 'Hello world' is broken into parts in Option B." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows sequence indexing/slicing syntax 'alphabet[1::2]', which helps a beginner understand that square brackets '[]' are used to access elements of a string or list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", + "rationale": "Explains string counting logic." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides a reference to the split operation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Introduces the concept of bracket indexing." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While '.count()' and '.split()' are mentioned, none of the snippets explain the 'len()' function or the '//' (floor division) operator, making Option C impossible to evaluate for a student with zero prior knowledge. Additionally, the specific indexing '[0]' is not explicitly defined as 'take the first element'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets fail to cover built-in math operators and basic length functions required for string manipulation questions.", + "missing_concepts": [ + "len() function", + "// (floor division) operator", + "List/String indexing [0]" + ], + "proposed_fix": "Add a snippet from a 'Week 1' or 'Introduction' lecture/exam that covers basic arithmetic operators (including //) and fundamental built-in functions like len()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet demonstrating 'len()' on a string and the difference between '/' and '//' operators, as well as basic '[0]' indexing.", + "why_helpful": "This would allow a student to solve Option C (len and floor division) and Option B (indexing the result of a split).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:02:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q12", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q12", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_2", + "question": "You need to write a function called main which accepts a list of integers as an argument. The function should return a tuple of two integers, in which the first is the sum of the squares of all even numbers, and the second is the sum of the squares of all odd numbers.\n\nFor example, calling the function as:\nmain(1, 2, 3, 4)\nshould return:\n(20, 10)\n\nWhich of the following blocks of code fits with the rest of the program and will you give the intended output?", + "options": { + "a": "for i in args:\n if i % 2 == 0:\n total_even += i**2\n else:\n total_odd += i**2\n\nreturn (total_even, total_odd)", + "b": "for i in args:\n if i % 2 == 1:\n total_even += i\n else:\n total_odd += i\n\nreturn (total_even**2, total_odd**2)", + "c": "for i in args:\n if i % 2 == 0:\n total_even.append(i**2)\n else:\n total_odd.append(i**2)\n\nreturn (sum(total_even), sum(total_odd))", + "d": "All of the given code blocks work as intended." + }, + "correct": "a", + "explanation": "Option A directly accumulates the squares of even numbers and odd numbers into the two totals and returns them as the required tuple.", + "code_context": "def main(*args):\n total_even = 0\n total_odd = 0\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly connects 'flexible number of arguments' (which maps to the *args in the question) with the specific logic of filtering and summing even integers, providing the conceptual bridge for the student to identify the correct pattern." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers flexible arguments (*args) and the concept of processing even integers." + }, + { + "item_id": "aiq-5", + "rationale": "Demonstrates returning multiple aggregated values (sum, min, max) from a collection of integers, which helps the student understand returning a result container like a tuple or dictionary." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Shows basic loop structure and variable initialization (count = 0), which is critical for distinguishing between the += (Option A) and .append (Option C) choices based on the provided code context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains *args and even-number logic." + }, + { + "item_id": "aiq-5", + "rationale": "Shows returning a composite object with summed values." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Provides loop and accumulation syntax examples." + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Demonstrates the syntax for returning tuples (a, b), which is the required return type in the question." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover *args, loops, and the general concept of summing even numbers, they do not show the modulo operator (%) for parity or the exponentiation operator (**) for squaring. A student without Python knowledge might struggle to confirm that i % 2 == 0 means 'even' or that i**2 means 'squared' without those explicit definitions.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The primary gaps are the mathematical syntax for parity checking and exponentiation, as well as the explicit distinction between integer accumulation and list appending.", + "missing_concepts": [ + "Modulo operator (%) for even/odd checks", + "Exponentiation operator (**)", + "Returning a tuple (val1, val2)" + ], + "proposed_fix": "Add an AI-generated example or technical note that specifically demonstrates basic numeric operations (%, **, //) and the syntax for returning multiple values as a tuple." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new AI Example titled 'Numeric Operations and Tuples'. Content: 'To square a number use x**2. To check if a number is even, use num % 2 == 0. To return two values together, use return (value1, value2).'", + "why_helpful": "This directly addresses the missing syntactical knowledge required to verify the math in Option A vs Option B.", + "why_maybe_unnecessary": "The student might guess the meaning of % and ** from context or general programming knowledge, but for 'zero prior knowledge', it is essential.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:03:06Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q13", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q13", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 1", + "question": "You have the following objects loaded in Python:\nname = \"Alice\"\nage = 25\ncountry = \"the USA\"\n\nYou need to print the following string:\nMy name is Alice. I am 25 years old, and I am from the USA.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"My name is {0}. I am {2} years old, and I am from {1}.\".format(name, country, age)\nprint(message)", + "b": "message = f\"My name is {name}. I am {age} years old, and I am from {country}.\"\nprint(message)", + "c": "message = 'My name is ' + name + '. I am ' + str(age) + ' years old, and I am from ' + str(country) + '.'\nprint(message)", + "d": "All of the given options are correct." + }, + "correct": "d", + "explanation": "All three code variants produce the target sentence: one uses format, one uses an f-string, and one uses string concatenation with str(age) and str(country).", + "code_context": "name = \"Alice\"\nage = 25\ncountry = \"the USA\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is the only one that directly addresses the task of printing variables (Name, Grade) within a template string, which is the core concept of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Covers variable interpolation into a string template, similar to the f-string and .format() requirements." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Provides context for handling student names (strings) and grades (floats/numbers) within dictionaries, which mirrors the data types in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions 'formatting' strings, though it focuses on phone numbers rather than general interpolation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Closest available match for string templating." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the snippets explain the specific syntax for f-strings, the .format() method with positional indexing, or the requirement to use str() when concatenating integers with strings. A student with zero knowledge would not be able to determine that all three methods are valid based on the provided candidates.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate pool lacks a snippet that explicitly compares or defines the various string formatting techniques in Python.", + "missing_concepts": [ + "f-string syntax (f\"...\")", + ".format() method and positional placeholders ({0}, {1})", + "String concatenation with the '+' operator and type conversion using str()" + ], + "proposed_fix": "Add a dedicated 'String Formatting' snippet to the study database that shows examples of f-strings, .format(), and concatenation side-by-side." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Python String Formatting' that includes: 1. f-strings: f'Hello {name}', 2. .format(): 'Hello {}'.format(name), and 3. Concatenation: 'Hello ' + name + ' is ' + str(age).", + "why_helpful": "This would directly allow a student to recognize that all three options in the exam question perform the same task correctly.", + "why_maybe_unnecessary": "If the student has already seen these in basic lecture notes, but the goal is to help a student with 'zero prior knowledge' using only snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:03:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q14", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q14", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 2", + "question": "Suppose you have the following DataFrame called df, and assume that pandas is already imported:\n\n Player Goals Assists\n0 John 5 2\n1 Jane 3 6\n2 Alex 2 4\n\nAll of the following lines of code make the same selection, but one of the results has a different datatype. Which one?", + "options": { + "a": "df.loc[:, 'Goals']", + "b": "df['Goals']", + "c": "df.loc[[0, 1, 2], 'Goals']", + "d": "df.loc[:, ['Goals']]" + }, + "correct": "d", + "explanation": "The first three expressions return a Series, while selecting with a list of column names returns a one-column DataFrame instead.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions that specifying ['B'] as a list is used to create a 'new DataFrame', which provides a subtle hint that list-based selection results in a DataFrame structure." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Implicitly associates list-based column selection with returning a DataFrame." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Shows that selecting multiple columns (A, C, D) results in a DataFrame, reinforcing the idea of lists and DataFrames." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame structure, helping a student identify what 'df' looks like." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Only snippet that mentions the syntax of using a list for a single column to get a DataFrame." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explicitly explain that selecting a single column with a string returns a Series while a list returns a DataFrame. A student with zero knowledge would likely not infer the datatype difference from the 'new DataFrame' hint alone.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack an explicit explanation of pandas return types (Series vs. DataFrame) based on selection syntax (string vs. list).", + "missing_concepts": [ + "Pandas Series vs. DataFrame datatypes", + "Return types of .loc with single labels vs. lists", + "The 'double bracket' or list-indexing rule in pandas" + ], + "proposed_fix": "Add a snippet or detail rule that explicitly compares df['col'] (Series) and df[['col']] (DataFrame)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet from Week 5 lecture materials (Inspecting and Selecting Data) that states: 'When selecting a single column from a DataFrame: using a string label (e.g., df['A']) returns a Series, while using a list of one label (e.g., df[['A']]) returns a one-column DataFrame.'", + "why_helpful": "This directly addresses the core concept of the exam question regarding return types.", + "why_maybe_unnecessary": "If the goal is only to provide exam question examples, adding a theoretical rule might deviate from the current snippet style.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:03:48Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q15", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q15", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_3", + "question": "Which code segment gives the same output as the following:\n\ndate1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module.", + "options": { + "a": "print((datetime(2023, 5, 1) - datetime(2023, 6, 1)).days)", + "b": "print((datetime(2023, 6, 1) - datetime(2023, 1, 5)).days)", + "c": "print((datetime.strptime('2023-6-1', '%Y-%d-%m') - datetime.strptime('2023-5-1', '%Y-%d-%m')).days)", + "d": "print((datetime.strptime('2023-06-01', '%Y-%m-%d') - datetime.strptime('2023-05-01', '%Y-%m-%d')).days)" + }, + "correct": "d", + "explanation": "Option D parses ISO-style date strings using the matching '%Y-%m-%d' format and subtracts the May date from the June date, giving the same day difference as the original code.", + "code_context": "date1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the integer difference, which is the core logic of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explains the fundamental mechanic of datetime subtraction and the .days attribute used in the question." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Shows a concrete code example of datetime arithmetic and usage of the .days attribute." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Covers the subtraction and .days attribute logic." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Provides syntax for creating datetime objects and performing subtraction." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain datetime arithmetic and the .days attribute. However, they do not explain the strptime/strftime format codes (%Y, %m, %d, etc.), making it impossible for a student without prior knowledge to determine if the parsing in Option D matches the input strings.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The main gap is the lack of information regarding string-to-date parsing (strptime) and the specific format codes needed to interpret the strings '2023-06-01' vs '2023-6-1'.", + "missing_concepts": [ + "strptime", + "strftime", + "datetime format codes (%Y, %m, %d)" + ], + "proposed_fix": "Add a reference snippet that lists common datetime format codes and demonstrates how strptime parses a string into a datetime object." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Formatting Cheatsheet' snippet. It should show: %Y (Year 2023), %m (Month 01-12), %d (Day 01-31), %H, %M, %S. Include an example: datetime.strptime('2023-06-01', '%Y-%m-%d').", + "why_helpful": "This allows students to translate the strings in the options into actual dates and compare them to the original code's dates.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:04:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q16", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q16", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Easy_2", + "question": "You have the following definition of a class called Flight. What would be the output if we execute the following statements?", + "options": { + "a": "'long'\n'cheap'", + "b": "'short'\n'expensive'", + "c": "'long'\n'expensive'", + "d": "'short'\n'cheap'" + }, + "correct": "a", + "explanation": "The first condition sets the KLM flight to Singapore to duration 'long', and the second condition sets the EasyJet flight to Spain to price 'cheap', so the two prints output 'long' and then 'cheap'.", + "code_context": "class Flight:\n def __init__(self, airline, destination):\n self.airline = airline\n self.destination = destination\n\n if self.airline == 'KLM' and self.destination == 'Singapore':\n self.duration = 'long'\n self.price = 'expensive'\n\n if self.airline == 'EasyJet' and self.destination == 'Spain':\n self.duration = 'short'\n self.price = 'cheap'\n\nprint(Flight('KLM', 'Singapore').duration)\nprint(Flight('EasyJet', 'Spain').price)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-06b21ad349", + "rationale": "Explains the core concept of the __init__ method as a constructor that initializes attributes and provides a direct syntax example (class Car) that maps to the question's structure." + }, + "top_three_snippets": [ + { + "item_id": "ks-06b21ad349", + "rationale": "Provides the fundamental explanation of class definitions, the constructor, and attribute assignment using 'self'." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Explains logical operators like '==', '!=', and 'and', which are critical for evaluating the if-statements inside the Flight class constructor." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides a secondary example of defining a class with multiple attributes, reinforcing the pattern of initializing state during object construction." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-06b21ad349", + "rationale": "Covers OOP structure and attribute assignment." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Covers string comparison and logical conjunction logic used in the conditions." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets explain both the OOP structure (how data is stored in attributes during initialization) and the logic gates (how the 'if' conditions evaluate). A student can trace 'KLM' and 'Singapore' to the first block and 'EasyJet' and 'Spain' to the second.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is fully coverable, the snippets don't explicitly show an example of conditional attribute assignment (if/else) inside a constructor.", + "missing_concepts": [ + "Conditional attribute assignment within __init__" + ], + "proposed_fix": "Add a lecture snippet or exam question that specifically demonstrates setting different attribute values based on constructor input parameters." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing a class where attributes are set conditionally, e.g., 'if age > 18: self.status = \"adult\" else: self.status = \"minor\"'.", + "why_helpful": "It directly mirrors the 'logic-heavy' constructor pattern seen in this exam question, reducing the mental leap for a novice.", + "why_maybe_unnecessary": "Basic OOP and Basic Conditions are present, and their combination is logically intuitive.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:04:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q17", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q17", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "6-string - operations - 1", + "question": "Consider the following code snippet. Which operation in the code snippet contains an error?", + "options": { + "a": "Operation 1", + "b": "Operation 2", + "c": "Operation 3", + "d": "None of the operations contains an error." + }, + "correct": "b", + "explanation": "Operation 2 is incorrect because join should be called as the separator string's method with a single iterable argument, for example '-'.join(word_list).", + "code_context": "text = \"The universe is vast and full of mysteries!\"\n\n# Operation 1:\nword_list = []\nfor word in text.split():\n word_list.append(word[::-1])\n\n# Operation 2:\njoined_text = ' '.join(word_list, '-')\n\n# Operation 3:\nreplaced_text = text.replace(\"mysteries\", \"secrets\")" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Explicitly mentions the .replace() method and its behavior, helping the student verify that Operation 3 is a valid Python string method." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Validates the use of the .replace() method seen in Operation 3." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates string slicing syntax (e.g., [1::2]), which helps a student understand the word[::-1] syntax used in Operation 1." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions the .split() method, allowing the student to recognize it as a standard string operation used in Operation 1." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Confirms .replace() syntax." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Confirms slicing syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Confirms .split() syntax." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Confirms that .append() is a valid list method, validating the logic in Operation 1." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide enough information to validate Operation 1 (split, append, slicing) and Operation 3 (replace). By process of elimination, a student might identify Operation 2 as the error. however, no snippet explicitly shows the correct syntax for the .join() method (which takes only one argument), meaning the student cannot 'prove' the error in Operation 2 directly from the provided text.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is no reference for the .join() method's syntax, specifically that it is called on the separator and takes exactly one iterable argument.", + "missing_concepts": [ + "str.join(iterable) syntax and argument count" + ], + "proposed_fix": "Add a snippet or documentation item that demonstrates joining a list of strings into a single string using a separator." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: separator = '-'; words = ['a', 'b', 'c']; result = separator.join(words).", + "why_helpful": "It would allow the student to see that .join() is called on the string separator and takes only the list as an argument, making the error in ' '.join(word_list, '-') (two arguments) obvious.", + "why_maybe_unnecessary": "Process of elimination might be sufficient for an exam setting if all other operations are clearly validated.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:04:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q18", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q18", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "6-strings - find - 2", + "question": "Suppose you have the following variables called sentence1 and sentence2 which contain strings. The sentences contain names, but they are not properly capitalized. You want to create a new string object called paragraph, with the proper nouns capitalized in the two sentences and the two sentences connected into one big string.\n\nThat is, if we execute the following line of code:\nprint(paragraph)\nthe output should be:\n\"Harry, Ron, and Hermione walked through the halls of Hogwarts; their footsteps echoing off the stone walls.\nThe Marauder's map in Harry's hands revealed the secret passageways and hidden rooms of the castle.\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor name in names:\n sentence1[sentence1.find(name)] = name.capitalize()\n sentence2[sentence2.find(name)] = name.capitalize()\nparagraph = sentence1 + \" \" + sentence2", + "b": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor word, name in zip(sentence1, names):\n if word == name:\n sentence1 = sentence1.replace(word, name.capitalize())\nfor word, name in zip(sentence2, names):\n if word == name:\n sentence2 = sentence2.replace(word, name.capitalize())\nparagraph = sentence1 + \" \" + sentence2", + "c": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nnew1 = ' '.join([word.capitalize() if word in names else word for word in sentence1])\nnew2 = ' '.join([word.capitalize() if word in names else word for word in sentence2])\nparagraph = new1 + \" \" + new2", + "d": "for word in ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']:\n sentence1 = sentence1.replace(word, word.capitalize())\n sentence2 = sentence2.replace(word, word.capitalize())\nparagraph = sentence1 + \" \" + sentence2" + }, + "correct": "d", + "explanation": "Option D correctly replaces each lowercase proper noun with its capitalized version in both strings and then concatenates the two sentences into paragraph.", + "code_context": "sentence1 = \"harry, ron, and hermione walked through the halls of hogwarts; their footsteps echoing off the stone walls.\"\nsentence2 = \"The marauder's map in harry's hands revealed the secret passageways and hidden rooms of the castle.\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the most relevant snippet as it explicitly deals with string manipulation (splitting and mapping) in a context of cleaning up names, which aligns with the question's goal of formatting names within strings." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides context for string transformations and handling name/location data." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions phone number formatting where digits are separated by characters, implying string cleaning or replacement logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Discusses casing (upper/lower case) in the context of anagrams, which highlights the importance of case sensitivity mentioned in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Closest match for string transformation." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Context for string formatting/cleanup." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the provided snippets define or demonstrate the '.replace()' method, the '.capitalize()' method, or string concatenation using the '+' operator. While some snippets mention strings and casing, they do not provide the syntactical proof needed for a student with zero prior knowledge to distinguish between the options (e.g., knowing that strings are immutable and thus Option A is invalid, or that '.replace()' exists and is the correct tool in Option D).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus on complex structures (OOP, Dictionaries, Pandas) but skip the fundamental string methods required for this specific question.", + "missing_concepts": [ + "str.replace()", + "str.capitalize()", + "String concatenation (+)", + "String immutability (to rule out item assignment in Option A)" + ], + "proposed_fix": "Add a snippet from the 'Week 1 - Objects and Names' or 'Week 4 - String Fundamentals' lecture that specifically lists common string methods like replace, capitalize, upper, and lower, along with concatenation examples." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new 'String Operations' snippet that covers: 1. str.replace(old, new) for substitution. 2. str.capitalize() and str.title() for casing. 3. '+' for joining strings. 4. An explicit note that strings cannot be modified in-place (no sentence[i] = 'X').", + "why_helpful": "This question tests basic string method knowledge. Without a reference to these specific methods, a student cannot confidently select 'd' over 'a' or 'c'.", + "why_maybe_unnecessary": "It is only unnecessary if the student has access to the full Python documentation or has already memorized basic string syntax.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:05:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q19", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q19", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - hard - 2", + "question": "Consider the following pandas DataFrame called df, and assume that Pandas is already imported.\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Name_Length that contains the length of each person's name\n- Operation 2: Replace all occurrences of the occupation 'Engineer' with 'Software Developer'\n- Operation 3: Extract the last two characters of each person's name and store them in a new column called Name_Suffix\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df['Name_Length'] = df['Name'].map(lambda x: len(x))\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:])", + "b": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].lambda x: x[-2:]", + "c": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[:-2])", + "d": "df['Name_Length'] = df['Name'].map(len)\ndf['Occupation'] = df['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:-1])" + }, + "correct": "a", + "explanation": "Option A correctly maps each name to its length, replaces only the Engineer entries, and slices the final two characters with x[-2:].", + "code_context": "Name Age Occupation\n0 John 25 Student\n1 Jane 30 Engineer\n2 Alex 35 Scientist\n3 Lisa 40 Doctor\n4 Mark 28 Architect" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains the .map() method for applying functions to Series, which is the primary mechanism used in the correct answer for operations 1 and 3." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly explains how to use .map() to transform Series values using functions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the basic syntax for creating a new column in a DataFrame (df['C'] = ...), essential for all three operations." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Reinforces the concept of calculating string lengths within a collection, which relates to the Name_Length requirement." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Covers the map() method usage." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers new column assignment." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides context for string length logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain how to create new columns and use the .map() method. However, they do not explain 'list comprehension' (used in Operation 2) or 'negative indexing string slicing' (used in Operation 3). A student without prior knowledge would see the syntax in Option A but wouldn't know why [-2:] is correct versus other slices.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets cover Pandas structural basics but miss core Pythonic transformations used in 'hard' Pandas questions.", + "missing_concepts": [ + "list comprehension for conditional replacement in columns", + "negative indexing for string slicing (e.g., [-2:])", + "lambda function syntax details" + ], + "proposed_fix": "Add a snippet specifically demonstrating string manipulation and conditional logic (ternary operators) within Pandas transformations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet illustrating: 1) Using .map(lambda x: x[-n:]) to extract suffixes. 2) Using list comprehension [value if condition else other for x in series] to replace specific values in a column. 3) Comparing .map(len) vs map(lambda x: len(x)).", + "why_helpful": "This would directly address the 'hard' components of the question (Operations 2 and 3) which are currently unsupported by the recommended snippets.", + "why_maybe_unnecessary": "Basic pattern matching might lead a student to Option A, but they wouldn't understand 'why' it works without these concepts.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:05:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q20", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q20", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - lambda - 2", + "question": "What will be printed by the following code?", + "options": { + "a": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 72 13\n1 B 45 19", + "b": "Product Units Price\n1 B 50 19\n0 A 100 10\n3 D 80 13\n2 C 200 15", + "c": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 80 13\n1 B 50 19", + "d": "Product Units Price\n2 C 200 15\n3 D 80 13\n0 A 100 10\n1 B 50 19" + }, + "correct": "c", + "explanation": "UnitsCorrected and Revenue are used only for sorting; df1 keeps the original Units and Price columns, and sorting by descending revenue gives rows C, A, D, B.", + "code_context": "import pandas as pd\nd = {'Product':['A', 'B', 'C', 'D'], 'Units':[100, 50, 200, 80], 'Price':[10, 19, 15, 13]}\ndf = pd.DataFrame(d)\ndf.loc[:, 'UnitsCorrected'] = df.loc[:, 'Units'].map(lambda x: 0.9*x if x < 100 else x)\ndf.loc[:, 'Revenue'] = df.loc[:, 'UnitsCorrected'] * df.loc[:, 'Price']\ndf = df.sort_values(by='Revenue', ascending=False)\ndf1 = df.loc[:, ['Product', 'Units', 'Price']]\nprint(df1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "It explicitly mentions the .map() method and applying functions to Series elements, which is the most complex part of the code (the lambda mapping)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains .map() for element-wise function application." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Explains vectorized operations (adding columns) which maps to the Revenue calculation." + }, + { + "item_id": "cs-b46633d18d", + "rationale": "Shows the syntax for creating a DataFrame from a dictionary, which is the first step of the problem." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Covers .map() usage." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers column creation and vectorized math." + }, + { + "item_id": "cs-b46633d18d", + "rationale": "Covers DataFrame initialization." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover DataFrame creation, column math, and .map(), they do not explain the 'lambda' syntax itself or the 'sort_values' method. A student wouldn't know how to evaluate the conditional '0.9*x if x < 100 else x' inside the lambda or what 'ascending=False' does to the order.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide a foundation for Pandas structure but fail to explain functional programming constructs (lambda) and data organization methods (sorting).", + "missing_concepts": [ + "Lambda functions with conditional logic (if-else ternary)", + "df.sort_values() and the ascending parameter", + "Projecting multiple columns using a list inside .loc" + ], + "proposed_fix": "Add a snippet demonstrating df.sort_values(by=..., ascending=False) and a basic explanation of lambda x: expression." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: df = df.sort_values(by='col', ascending=False) with a comment: '# Sorts the table by the values in \"col\", from highest to lowest'.", + "why_helpful": "Essential for determining which rows appear first in the final output (Product C then A).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining lambda: 'df[\"A\"].map(lambda x: x*2) means apply the rule \"take x and return x times 2\" to every row in column A'.", + "why_helpful": "The most difficult syntactic hurdle for a zero-knowledge student in this specific problem.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:05:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q21", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q21", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_2", + "question": "You have the following definition for a class called Calendar.\n\nThe method check_overlap() should return True if there are two overlapping events and False if the two events are not overlapping.\n\nFor example, if we have the following Calendar objects:\nevent1 = Calendar('Coffee meeting', '01-06-2023 9:30', 20)\nevent2 = Calendar('Writing session', '01-06-2023 10:00', 150)\nevent3 = Calendar('Lunch meeting', '01-06-2023 12:00', 45)\n\nthe following command should return False:\nprint(event1.check_overlap(event2))\n\nand the following command returns True:\nprint(event2.check_overlap(event3))\n\nDoes the code segment given above do what you want? If not, then why not?\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the condition provided after the return keyword is incorrect.", + "c": "This code segment does not work because the syntax to parse the input string to create a datetime object is incorrect.", + "d": "This code segment does not work because the __init__ method needs 4 parameters and only 3 arguments are passed." + }, + "correct": "a", + "explanation": "The datetime format string matches the input values, timedelta(minutes=length) creates the correct end time, and the overlap condition correctly detects whether two intervals intersect.", + "code_context": "from datetime import datetime, timedelta\n\nclass Calendar():\n def __init__(self, event, start, length):\n self.event = event\n self.start = datetime.strptime(start, '%d-%m-%Y %H:%M')\n self.end = self.start + timedelta(minutes=length)\n def check_overlap(self, other):\n return self.start < other.end and self.end > other.start" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Helps clarify the syntax and logic of a method ('compare') that takes 'self' and 'another' object as arguments, which is structurally identical to the 'check_overlap(self, other)' method in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates how classes use methods to compare one instance to another ('other'), supporting the logic in check_overlap." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides an example of the __init__ constructor and attribute initialization, helping verify the class structure and constructor argument counts." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Explains method-based comparisons between class instances." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Validates the standard syntax for Python class initialization (__init__)." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets explain general OOP structure (classes and methods), none of the available snippets mention the 'datetime' module, 'strptime' formatting strings, or 'timedelta' arithmetic. A student with zero knowledge cannot verify if '%d-%m-%Y %H:%M' correctly parses '01-06-2023 9:30' or if the interval overlap logic is correct without a datetime-specific reference.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of 'datetime' and 'timedelta' documentation or examples in the recommended snippets.", + "missing_concepts": [ + "datetime.strptime", + "Time formatting codes (%d, %m, %Y, %H, %M)", + "timedelta arithmetic", + "Interval overlap boolean logic" + ], + "proposed_fix": "Add a snippet or documentation entry specifically for the datetime library that shows how to parse strings and calculate durations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: 'from datetime import datetime, timedelta; dt = datetime.strptime(\"23-03-2026 14:00\", \"%d-%m-%Y %H:%M\"); end = dt + timedelta(minutes=30)'.", + "why_helpful": "This would allow a student to verify the syntax for parsing (strptime) and time addition (timedelta) used in the question.", + "why_maybe_unnecessary": "The question hint provides some info on timedelta, but not on strptime or format strings.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining the logic for checking if two time intervals (start1, end1) and (start2, end2) overlap: 'start1 < end2 and end1 > start2'.", + "why_helpful": "This is a common exam pattern that is difficult to deduce with zero prior logic/programming knowledge.", + "why_maybe_unnecessary": "Some students might be able to figure this out logically if they draw it, but it's a high cognitive load.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:06:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q22", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q22", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_1", + "question": "You want to create a DataFrame called df that has the following format:\n\n Day Month Year\n01-01-23 1 1 2023\n08-01-23 8 1 2023\n15-01-23 15 1 2023\n22-01-23 22 1 2023\n29-01-23 29 1 2023\n\nWhich of the following code segments achieves what you want?\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module, as well as the pandas module (via: import pandas as pd).\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "dates = [(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=[date.strftime('%d-%m-%y') for date in dates])", + "b": "dates = [(datetime(2023, 1, 1) + timedelta(days=7*i)).strftime('%d-%m-%y') for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=dates)", + "c": "day = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).day for i in range(5)])\nmonth = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).month for i in range(5)])\nyear = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).year for i in range(5)])\ndf = pd.DataFrame(data=[day, month, year])", + "d": "df = pd.DataFrame(index=[(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)],\n {'Day': [date.days for date in index],\n 'Month': [date.months for date in index],\n 'Year': [date.year for date in index]})" + }, + "correct": "a", + "explanation": "Option A keeps real datetime objects long enough to derive day, month, year, and then formats those dates into the desired string index for the DataFrame.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that introduces the relationship between 'datetime' and 'timedelta' objects, which is the core logic required to generate the sequence of dates in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Introduces the datetime and timedelta classes and mentions accessing attributes like '.days' on timedelta objects." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Illustrates how DataFrames use columns (Series) of data, which helps a student understand the 'data' dictionary structure used in options A and B." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Shows list and variable structures, assisting in the interpretation of the list comprehensions used to build the 'dates' list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Essential for understanding the library classes mentioned in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Necessary to understand the construction of a DataFrame from a dictionary." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the question provides a hint for timedelta parameters, the candidate snippets fail to explain: 1) datetime attributes (.day, .month, .year), 2) the .strftime() method, and 3) that .strftime() returns a string. Without this, a student cannot know that Option B is invalid because it tries to call .day on a string, nor can they confirm Option A is correct for formatting the index.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide the basic 'container' (Pandas) and 'type' (Datetime) context, but lack the specific 'member' (attributes/methods) knowledge required for this 'Hard' level question.", + "missing_concepts": [ + "datetime object attributes: .day, .month, .year", + "datetime.strftime() method and common format codes (e.g., %d, %m, %y)", + "The fact that strftime returns a string (type conversion)" + ], + "proposed_fix": "Add a snippet or detail rule explaining how to extract components from a datetime object and how to format it as a string for display." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Datetime Attribute Extraction and Formatting'. Content: 'Given dt = datetime(2023, 1, 1), use dt.day, dt.month, and dt.year to get integers. Use dt.strftime(\"%d-%m-%y\") to create a formatted string like \"01-01-23\".'", + "why_helpful": "Directly provides the information needed to distinguish between the datetime object (needed for attributes) and the formatted string (needed for the index).", + "why_maybe_unnecessary": "The student might guess based on the intuitive names of '.day' and '.year', but they wouldn't know 'strftime' or how it differs from a raw object.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:06:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q23", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q23", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Function_3", + "question": "You have the following definition of a class called Pack.\n\nYou want to add to this class a method called fitting() that calculates how many times another object of the class Pack would fit inside this object.\nThe method should return the number of times these other objects would fit completely in this object, and the final value.\nThe final value is the sum of all values of all objects that fit in it, plus the value of the carrying object self.\n\nFor example, if we execute the lines of code:\nbackpack = Pack(size=15, value=20)\nbook = Pack(size=4, value=10)\nbackpack.fitting(book)\n\nthe output should be:\nAmount: 3. Value: 50.\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def fitting(self, other):\n if self.size > other.size:\n self.total = (self.size // other.size) * other.value + self.value\n return f'Amount: {self.size // other.size}. Value: {self.total}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "b": "def fitting(self, other):\n if self.size > other.size:\n return f'Amount: {self.size // other.size}. Value: {other.value * other.size}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "c": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return f'Amount: {self.amount}. Value: {self.total}.'", + "d": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return 'Amount: {}. Value: {}.'.format(self.amount, self.value if self.size > other.size else self.total)" + }, + "correct": "a", + "explanation": "Option A uses integer floor division to count only full fits, adds the carried items' value plus self.value, and returns zero items with self.value when the other object does not fit.", + "code_context": "class Pack:\n def __init__(self, size, value = 0):\n self.size = size\n self.value = value\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet is critical because it demonstrates writing a method that compares 'self' to 'another' object of the same class, showing the exact attribute access pattern (e.g., self.score vs other.score) required by the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how methods interact with other instances of the same class and use comparison logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational context for class definition and attribute initialization (self.name, self.mode)." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Demonstrates the 'if/else' conditional structure needed to handle the two different return cases in the fitting() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Method-level attribute comparison logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Class/attribute boilerplate." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Conditional branching logic." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows string formatting with placeholders, which helps decode the f-string/format syntax in the options." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "Existing snippets cover class structure, method definitions, attribute access on 'self' vs 'other', and conditionals. However, no snippet explains the difference between floor division (//) and standard division (/), which is the primary technical distinction between the correct option A and the incorrect options C/D.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student can figure out the OOP structure and logic flow from the snippets, but might struggle to choose between (/) and (//) without an arithmetic operator reference.", + "missing_concepts": [ + "Integer/Floor division (//) vs Floating point division (/)", + "F-string syntax specifically" + ], + "proposed_fix": "Add an AI-generated or source-based snippet covering basic arithmetic operators, emphasizing that // is used for 'fitting' or 'counting whole units'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A reference card for Python Arithmetic Operators: + (addition), - (subtraction), * (multiplication), / (division), // (floor division/integer), % (modulo). Include an example like '15 // 4 = 3 (fits 3 times)'.", + "why_helpful": "The question hinges on calculating how many times something 'fits completely', which requires // instead of /.", + "why_maybe_unnecessary": "Students might infer // is 'special' for integers given the context 'Amount: 3' in the example output.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:06:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q24", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q24", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Hard_1", + "question": "You have the following definition for a class called Piece.\n\nAnd the creation of three objects with the help of the class definition:\na = Piece(diagonal=True, straight=False, initial_position=(0, 0))\nb = Piece(diagonal=False, straight=True, initial_position=(4, 3))\nc = Piece(diagonal=True, straight=True, initial_position=(9, 6))\n\nIf we run the following statements:\nprint(a.check_move((4, 4)))\nprint(b.check_move((5, 5)))\nprint(c.check_move((6, 6)))\n\nThis will print 3 Boolean values. Of these values, how many times will this be True?", + "options": { + "a": "0", + "b": "1", + "c": "2", + "d": "3" + }, + "correct": "b", + "explanation": "The first move fails because the row and column differences are both 4, which is above the allowed maximum of 3. The second fails because a straight-only piece cannot move diagonally. The third succeeds because a piece that can move straight and diagonally may move along the same column within 3 steps, so exactly one result is True.", + "code_context": "class Piece:\n def __init__(self, diagonal, straight, initial_position):\n self.diagonal = diagonal\n self.straight = straight\n self.initial_position = initial_position\n\n def check_move(self, target_position):\n self.target_position = target_position\n self.row_diff = self.target_position[0] - self.initial_position[0]\n if abs(self.row_diff) > 3:\n return False\n self.col_diff = self.target_position[1] - self.initial_position[1]\n if abs(self.col_diff) > 3:\n return False\n\n if self.diagonal and (not self.straight):\n return abs(self.row_diff) == abs(self.col_diff)\n if self.straight and (not self.diagonal):\n return abs(self.row_diff) == 0 or abs(self.col_diff) == 0\n if self.straight and self.diagonal:\n return (abs(self.row_diff) == abs(self.col_diff)) or (abs(self.row_diff) == 0 or abs(self.col_diff) == 0)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the essential syntax for defining a class, using __init__, and setting attributes, which mirrors the structure of the Piece class in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Explains the foundational OOP concepts of class definition and attribute initialization used in the question's code." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Clarifies logical operators (and, or, !=) and type conversion (int), which are critical for evaluating the Boolean expressions in the check_move method." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows a method (compare) inside a class that performs logic on attributes, helping a student understand how check_move operates on the Piece object." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Covers class/attribute basics." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Covers logical evaluation." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Covers method logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Though about Pandas, it shows coordinate-like indexing (rows/cols) which might help a student infer how tuple indexing works, though it's a weak link." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain how classes are built and how logical 'and/or' works. However, there is no snippet explaining the 'abs()' function or how to index into a tuple/list (e.g., target_position[0]), both of which are central to calculating the row and column differences in this specific problem.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "A student with zero knowledge would struggle with the mathematical operations and data structure access inside the method.", + "missing_concepts": [ + "abs() function for absolute values", + "Indexing into tuples/lists (e.g., sequence[0])", + "The 'self' keyword and attribute access syntax" + ], + "proposed_fix": "Add a snippet or reference explaining basic built-in functions like abs() and how to access elements in a coordinate pair (tuple indexing)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining 'self' and tuple indexing. Example: 'In Python classes, self.attribute refers to the data stored in that object. If a variable represents a position like (row, col), position[0] gets the row and position[1] gets the col.'", + "why_helpful": "The question relies heavily on understanding that initial_position[0] is a number being subtracted from target_position[0]. Without knowing what the brackets do, the math is impossible to trace.", + "why_maybe_unnecessary": "Some students might guess indexing based on other languages, but it's risky for zero-knowledge users.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for common built-in functions: 'abs(x) returns the absolute (positive) value of a number. For example, abs(-3) is 3.'", + "why_helpful": "The logic for distance (row_diff > 3) and diagonal movement (abs(row_diff) == abs(col_diff)) requires knowing what abs() does.", + "why_maybe_unnecessary": "Abs is common in math, but its specific Python syntax should be confirmed.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:07:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 357615", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "All three expressions evaluate to True: 2 * 3 = 6 equals x[2][1], 3 + 5 = 8 equals x[-1][1], and 7 - 5 = 2 equals x[0][1].", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you have a list called x containing tuples, where x = [(1, 2), (3, 4), (5, 6), (7, 8)] Which of the following lines of code will print True?", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This snippet is a verbatim match for the question and provides the step-by-step arithmetic evaluation for each option (e.g., explaining that Option A evaluates to 2 * 3 == 6)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Verbatim match with explicit evaluation logic for the expressions." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Another verbatim match that confirms all options evaluate to True, providing redundant but helpful verification." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This single snippet provides the full answer and the logic required to verify it." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact question and the full evaluation of the code logic, making it trivial to answer even without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the specific answer is provided, there is no general explanation of how nested indexing or negative indexing works for a student to apply to similar but different problems.", + "missing_concepts": [ + "Negative indexing (e.g., x[-1] refers to the last element)", + "Nested indexing (e.g., x[i][j] accesses element j within the i-th sub-element)" + ], + "proposed_fix": "Add a theoretical reference card or key point snippet explaining Python indexing rules (0-based, negative indexing, and multi-dimensional access)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Python List & Tuple Indexing. 1. Indexing starts at 0. 2. Negative indices count from the end (-1 is the last item, -2 is second to last). 3. For nested structures like x = [(a, b)], x[0][1] accesses the second item of the first tuple.", + "why_helpful": "This would allow the student to understand *why* x[0][1] is 2, rather than just relying on a matched example.", + "why_maybe_unnecessary": "The exact question already exists in the exam bank snippets, so for this specific exam, the student can just match the pattern.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:07:37Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q02", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q02", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 357607", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "The function called power should not return the string 'The result of {} ** {} is: {}'.format(num, factor, result), but the value of result.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "Result is a local name that cannot be referenced outside of the function power." + }, + "correct": "d", + "explanation": "`result` is defined inside the function `power`, so it is local to that function. The statement `print(result)` outside the function therefore raises a name error because `result` is not defined there.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}'.format(num, factor, result)\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "This snippet contains a nearly identical question and provides a clear explanation that variables defined inside a function are local and cannot be accessed in the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a direct example of the error in the question, identifying 'result' as a local variable." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the fundamental concept of local and global scope, defining local names as those assigned inside a function." + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "Explicitly states that 'local names are gone after function ends', which directly explains why the print(result) call fails." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the theoretical foundation for local names and scope." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Applies the theory to the exact code structure presented in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets provide both the theoretical definition of local scope and a direct application of that concept to a code snippet identical to the one in the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets cover the topic comprehensively.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:07:51Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 355235", + "question": "What will be printed by the following code segment?", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[]", + "d": "[None]" + }, + "correct": "d", + "explanation": "The code appends list-typed elements to `y`, but the return expression uses `append`, which itself returns `None`. The page marks option D as correct, so the intended evaluated output is `[None]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n\n return [y.append(i)]\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What will be printed by the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "This snippet explains the logic of `type(i) == type(x)`, helping the student understand that the loop identifies elements whose type matches the container (i.e., identifying lists within the list)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Explains the type-checking loop logic which is identical to the first half of the question code." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows the `.append()` method in use, which is necessary for recognizing what the code is attempting to do with the list." + }, + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "rationale": "Includes 'None' as a possible output option (Option D), which aligns with the correct answer in the target question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Covers the type-comparison logic used in the filter loop." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows basic list modification methods like append." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets perfectly explain the type-filtering logic (identifying the empty list `[]`). However, no snippet explains that the `.append()` method returns `None`. A zero-knowledge student would likely conclude the answer is `[[]]` (Option B) because they understand the filter, but miss the 'trick' where the return statement wraps the result of an `append` call.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets cover loop logic and type identification but miss critical technical details regarding method return values and post-loop variable scope.", + "missing_concepts": [ + "The list.append() method modifies the list in-place and returns None.", + "The loop variable (i) remains accessible and holds its last value after a for-loop completes." + ], + "proposed_fix": "Add a snippet or documentation item explaining that in-place methods (append, remove, sort, extend) return None, specifically contrasting `return mylist` with `return mylist.append(x)`." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'List Methods and Return Values': Common list methods like .append(), .remove(), and .sort() perform actions 'in-place'. This means they change the list but return the value None. If you see code like 'print(mylist.append(5))' or 'return [mylist.append(5)]', the output will be None or [None].", + "why_helpful": "This addresses the specific 'trap' in the question that separates students who understand loop logic from those who understand Python's method return conventions.", + "why_maybe_unnecessary": "It is a very specific technical detail, but it is a recurring theme in 'Return Behavior' exam questions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:08:19Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "function defaults and loops", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "This code produces an error as there is a missing argument when calling main.", + "b": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10']", + "c": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')", + "d": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10',\n '1 * 11 = 11']" + }, + "correct": "b", + "explanation": "`main(1)` is valid because `y` has default value `11`. The loop starts at `i = 1` and runs while `i < y`, so it appends the multiplication strings for 1 through 10 and stops before 11.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nprint(main(1))" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "Suppose you have the following function, which takes two integers as arguments: What will be printed by the following line of code: print(main(1))", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ], + "evidence_topics": [ + "Loops" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This is an identical question with an explanation that explicitly states y=11 is a default argument and the loop runs from 1 to 10." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Directly answers the specific question and explains the default argument and loop logic." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Another direct match for the question, reinforcing the behavior of the default argument y=11." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Provides a clear example of how multiple default arguments work and how they are overridden or kept when calling the function." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Provides the exact solution and logic for the while loop and default value." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question and explanation are present in the provided snippets, making the answer directly accessible.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets provide a 1:1 match for the question, so there are no functional gaps for this specific test case.", + "missing_concepts": [], + "proposed_fix": "No fix required as the exact content is available." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:08:32Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "list slicing and sets", + "question": "Suppose you have a list called x, where:\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Option A removes duplicates and sorts descending, which gives `[5, 4, 3, 2, 1]`. Option B takes every second element from the end of the symmetric list and also prints `[5, 4, 3, 2, 1]`.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n# target output:\n# [5, 4, 3, 2, 1]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "Suppose you have a list called x, where: Which of the following code segments will print the following list? [5, 4, 3, 2, 1]", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet contains the exact question and a clear explanation of both Option A (set/sorting) and Option B (slicing), though the text for Option B is slightly truncated." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Identical question match; explains set(x) for uniqueness and reverse sorting." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Another identical match providing a slightly different wording for the explanation of Option A." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides additional context for list slicing syntax [start:stop:step], which helps decode the [::-2] logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Contains the literal question and answer logic for both methods being tested." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets provide the exact question and explain why both segments produce the desired output, specifically mentioning set-based deduplication and reverse-step slicing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the direct answer, but the explanation for the slicing logic ([::-2]) is cut off in the available search text.", + "missing_concepts": [ + "Negative step slicing mechanics (stepping backwards)" + ], + "proposed_fix": "Ensure the explanation for slicing in the snippet is fully captured to clarify that -2 steps backwards by two elements." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "proposal": "Update search_text to include: 'Option B uses slicing [::-2] to step backwards through the list by 2, which skips the duplicates and reverses the order.'", + "why_helpful": "It clarifies the 'magic' of the slicing syntax which is currently truncated in the snippet.", + "why_maybe_unnecessary": "The student might infer the result because it is a direct match of a known exam question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:08:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "keyword arguments", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "To sum the numeric keyword-argument values, the function must iterate over `kwargs.values()`. Option A adds the string keys instead of the prices, and Option C incorrectly tries to unpack `kwargs.keys()`.", + "code_context": "main(apple=1.99, banana=0.99, orange=1.49)\n# should return 4.47" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments. For ex", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "This snippet contains the exact prompt of the question, providing the student with the context of summing keyword argument values, although it lacks the specific code implementation for the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Identical question prompt; identifies the task as summing flexible keyword argument values." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Explains that flexible keyword arguments are handled as key-value pairs, which helps a student understand that the input is a dictionary-like object." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary iteration ('for letter in string') and access ('counts[letter]'), providing a conceptual bridge to how dictionaries are handled in loops." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Matches the exam question context perfectly." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Connects 'keyword arguments' to 'key-value pairs'." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the exact question text is present in the snippets, the critical technical detail (choosing between .values(), .items(), and .keys()) is not explicitly explained. A student with zero knowledge would know *what* they are trying to do but not *which method* provides the numeric values vs. the string keys.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the 'what' (summing keyword arguments) but lack the 'how' (dictionary methods for iteration).", + "missing_concepts": [ + "Difference between .keys(), .values(), and .items() in dictionary iteration", + "Syntax for unpacking items in a loop (e.g., 'for k, v in kwargs.items()')", + "The fact that **kwargs acts as a dictionary inside the function" + ], + "proposed_fix": "Add a dedicated 'Dictionary Iteration' snippet that explicitly labels what each method returns (keys, values, or both)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Dictionary & **kwargs Iteration. Content: 'def main(**kwargs): \\n # kwargs.keys() -> names (strings)\\n # kwargs.values() -> values (numbers/data)\\n # kwargs.items() -> both (name, value)\\n for val in kwargs.values(): total += val'", + "why_helpful": "This directly addresses the trap in the exam question by explaining the return types of dictionary methods.", + "why_maybe_unnecessary": "If the student already understands basic dictionary concepts from a general programming background, they might guess correctly, but for a zero-knowledge student, this is essential.", + "recommended_direction": "add_this" + }, + { + "kind": "edit_existing", + "target_item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "proposal": "Expand search_text to include the solution logic: 'To sum prices passed as keywords, iterate over kwargs.values() to get the numbers, not the keys.'", + "why_helpful": "Turns a placeholder into a functional solution reference for that specific recurring exam question.", + "why_maybe_unnecessary": "", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:09:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {word: len for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to the length of that word. The other options either reverse key/value order or use invalid logic.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text, including the list 'words' and the goal to create 'word_lengths', effectively serving as a direct answer key." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Directly matches the question and likely provides the correct code segment in its full text." + }, + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Features a similar 'Which of the following code segments will work' format for dictionary creation, helping the student recognize patterns in dictionary logic." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows a scenario where keys (names) are mapped to values (ages), reinforcing the concept of transforming lists into dictionary pairs." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "As an identical question, this is sufficient to solve the problem by recognition." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the identical question from a previous exam (Resit 22/23).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While a direct match exists, there is no conceptual explanation of the dictionary comprehension syntax ({key: value for item in iterable}).", + "missing_concepts": [ + "Dictionary Comprehension Syntax", + "Dictionary Unpacking Rules" + ], + "proposed_fix": "Add a conceptual key point or AI-generated section specifically defining the syntax and common pitfalls (like key/value order) of dictionary comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Key Point' explaining Dictionary Comprehensions: '{k: v for k in list}' where 'k' is the key and 'v' is the value. Emphasize that the key comes before the colon.", + "why_helpful": "It gives the student the 'rule' instead of just a specific answer, allowing them to solve variations of the question.", + "why_maybe_unnecessary": "The direct match in the exam snippets might be enough for a student looking for a quick fix.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:09:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades.\n\nThe students list contains strings representing the names of students.\nThe grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears. B builds lists of students per grade instead of counting them.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text, the expected output, and explicitly states that 'Option a' is the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Exact match for the question and identifies the correct code segment." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the same pattern: creating a dictionary from a list where the keys are the list items. It also confirms that a similar 'Option A' logic is valid for this pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides context for creating a dictionary from two parallel lists (names and ages), which mirrors the students and grades structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Since this is the identical question with the answer provided, it is sufficient on its own." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the exact question from the exam bank along with the solution.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps exist because the exact question is present in the source materials.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:09:51Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the right result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This snippet is an exact match for the question, containing the same 'math_scores' dictionary, the same scenario, and mentions the code segments 'a' and 'b'." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Identical question and data structure; directly answers the problem." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates calculating an average from a dictionary, which is the core logic required for the math scores problem." + }, + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Shows a structurally identical dictionary (employee_ratings) and the goal of finding/printing specific names based on values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Contains the specific problem text and data, making it the most direct reference for a student with no prior knowledge." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes a snippet that is an exact replica of the question. Even without Python knowledge, the student can match the 'math_scores' variable and the problem description to the snippet.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While an exact match exists, the snippet text in 'exam-extra_practice-4' mentions an indentation error in Option A, whereas the target question's answer is 'c' (both work). This could cause confusion.", + "missing_concepts": [ + "sum() and len() functions on dictionary values", + "Explicit confirmation that both iterating via .keys() and iterating directly over a dictionary yield the same keys." + ], + "proposed_fix": "Add a conceptual snippet explaining that sum(d.values()) / len(d) is the standard way to find a dictionary average, and that 'for k in d' is equivalent to 'for k in d.keys()'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Analytics' snippet: 'To calculate average: avg = sum(my_dict.values()) / len(my_dict). To find items above average: for key in my_dict: if my_dict[key] > avg: print(key). Note: for key in my_dict is the same as for key in my_dict.keys().'", + "why_helpful": "It explains the underlying logic of the two options (A and B) in the question, clarifying why they are functionally identical despite different syntax.", + "why_maybe_unnecessary": "The student might just rely on matching the exact question if they find snippet 4.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:10:10Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the logic of list comprehensions as a filter ('keeps numbers that satisfy conditions'), which is the core structure of the code segment." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Clarifies how the 'if' condition inside a list comprehension acts as a filter for elements." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Demonstrates string iteration using 'for letter in string', helping a beginner understand how the comprehension traverses 'x'." + }, + { + "item_id": "kp-2", + "rationale": "Explains that methods are functions attached to objects (like .islower() to char) and that they return values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the comprehension filtering logic." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Shows string iteration." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The structural logic (comprehension and iteration) is covered by existing snippets, but the specific behavior of '.islower()'—particularly that it returns False for spaces and punctuation—is not documented in any candidate snippet.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The student can understand 'how' the loop runs but not 'what' the specific filter (.islower) does with non-alphabetic characters like ' ', '!', and ','.", + "missing_concepts": [ + "islower() method definition", + "islower() behavior on non-alphabetic characters (spaces/symbols)" + ], + "proposed_fix": "Add a Key Point detailing common string boolean methods (islower, isupper, isdigit) and their results on various character types." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: String Case Testing. .islower() returns True ONLY if the character is a lowercase letter. It returns False for uppercase letters, spaces, and punctuation (e.g., 'a'.islower() is True, but 'A', ' ', and '!' are False).", + "why_helpful": "Directly explains why spaces and punctuation are excluded from the result list in the question.", + "why_maybe_unnecessary": "A student might guess 'islower' refers only to lowercase letters, but 'zero knowledge' implies they might not know if a comma has a case.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:10:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "Explains the `append` method, which is the only list-modifying operation in the question's code. However, it does not explain the loop structure or the math operators." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Clarifies how `.append()` works with lists, which is central to building the result list." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains that `print` is a built-in function used to output arguments to the screen, helping a novice understand the final line." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a `for x in lst` loop and `.append()`, providing some pattern matching for how elements move from one list to another." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Covers list mutation (append)." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Covers output (print)." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows basic loop iteration and list accumulation." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "Crucial concepts are missing: the `zip()` function, which pairs elements from two lists, and the floor division operator `//`. Without knowing `zip()`, a student won't know that 'a' comes from list1 and 'b' from list2. Without knowing `//`, they cannot perform the calculation required to distinguish between options (b) and (d).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets do not define the 'zip' function or the 'floor division' operator, both of which are required to solve the logic and the arithmetic of the question.", + "missing_concepts": [ + "zip() function for parallel iteration", + "floor division operator (//)", + "unpacking multiple variables in a for loop (for a, b in ...)" + ], + "proposed_fix": "Add a manual or AI-generated snippet specifically covering common Python operators (//, %, **) and the built-in zip() function." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Python Arithmetic Operators. Content: + (addition), - (subtraction), * (multiplication), / (division), // (floor division: divides and rounds down to nearest integer), % (modulo: remainder), ** (exponentiation). Example: 5 // 2 results in 2.", + "why_helpful": "Directly explains the // operator used in the code context to reach the correct answer.", + "why_maybe_unnecessary": "Basic math might be assumed, but floor division is specific to programming languages.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Parallel Iteration with zip(). Content: The zip() function takes multiple iterables (like lists) and aggregates them into tuples. Example: for a, b in zip([1, 2], [3, 4]): prints (1, 3) then (2, 4).", + "why_helpful": "Explains how the 'for a, b in zip(list1, list2)' loop processes both lists simultaneously.", + "why_maybe_unnecessary": "None; it is critical for this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:10:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "This snippet is the exact same question and provides the logic for why negative steps like [::-2] and [-1::-2] produce the desired list." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Identical question and explanation of negative slicing logic." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Shows another example of list manipulation to achieve a reversed sequence [5, 4, 3, 2, 1]." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Explains the mechanics of slicing with a step (range(0, 7, 3)) and partition slicing (x[0:3])." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Directly answers the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One of the snippets is the exact exam question being asked, including the start of an explanation that validates the correct slicing logic for multiple options.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact answer is present, a student without the specific 'extra practice' snippet would struggle to understand nested slicing (like option A or C) because the concepts of 'slice of a slice' aren't explicitly taught in a general way in the other snippets.", + "missing_concepts": [ + "Nested slicing (applying a second slice to the result of a first slice)", + "Formal definition of [start:stop:step] syntax" + ], + "proposed_fix": "Add a foundational snippet or subtopic detail explaining that 'numbers[a:b:c][x:y:z]' applies the second slice to the intermediate list produced by the first." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Nested Slicing Logic. Content: Slicing creates a new list. You can apply another slice immediately after: my_list[start:stop:step][new_start:new_stop:new_step]. The second slice acts on the results of the first.", + "why_helpful": "This helps the student evaluate options A and C which use two sets of brackets.", + "why_maybe_unnecessary": "The student might just find the exact matching question snippet and stop there.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:11:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", leaving only the second occurrence replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "While the topic is loops, this snippet explicitly demonstrates string slicing syntax (`alphabet[1::2]`), which is the fundamental mechanism used in Option A of the question to surgically replace text." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides the only direct syntax example of string slicing (accessing parts of a string using brackets)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Involves extracting specific substrings from complex strings (URLs), mirroring the logic needed to find specific indices in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Deals with strings where characters (dashes) need to be handled/formatted, which conceptually relates to the .replace() logic in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Slicing syntax reference." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "String parsing logic reference." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The candidate snippets are almost entirely irrelevant to the specific 'replace' count argument and the specific 'find' start-index argument. While the question provides a hint for .find(), no snippet explains that .replace(old, new, count) limits replacements to the first N occurrences, which is critical to understanding why Option B works. Slicing is shown but not explained in a way that helps a zero-knowledge student understand `sentence[index + 4:]`.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of documentation or examples for string methods with optional arguments (like count in replace or start in find) and no clear explanation of 'surgical' string reconstruction using concatenation and slicing.", + "missing_concepts": [ + "str.replace(old, new, count) - the 'maxreplace' parameter", + "str.find(sub, start) - the 'start' index parameter beyond what is in the question hint", + "Using slicing for index-based string reconstruction (sentence[:i] + 'new' + sentence[i+n:])" + ], + "proposed_fix": "Add a snippet or topic card specifically covering 'String Manipulation and Surgical Replacement' that demonstrates find(), index-based slicing, and the count parameter in replace()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card titled 'Targeted String Modification' showing: 1. .replace('text', 'new', 1) only replaces the first match; 2. .find('text', 5) starts searching after index 5; 3. sentence[:5] + 'new' + sentence[10:] replaces characters between index 5 and 10.", + "why_helpful": "This directly maps to the mechanics of both Option A and Option B, allowing a student to verify the multi-step replacement logic in Option B and the slicing offsets in Option A.", + "why_maybe_unnecessary": "The question contains a hint for find(), but it is insufficient for a zero-knowledge student to confidently evaluate the replace() logic or the math behind index+4 slicing.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:11:34Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the requested sentence exactly, including the word \"and\" before the final fruit. Option A joins the list as \"apple, banana, orange\" and does not produce the exact requested wording.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves formatting a string with variables from a list of items (Name and Grade), which is the closest conceptual match to the f-string formatting required by the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Contextual match for printing formatted strings using data from lists." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows list/string indexing syntax (e.g., [1::2]), which is necessary to understand Option B's use of fruits[0], fruits[1], etc." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions string methods like .map() and splitting, providing some context for string manipulation methods like .join()." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Provides the 'string with placeholders' pattern." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides the indexing syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides string manipulation context." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Shows a list of dictionaries, helping a student understand how lists store multiple items." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "No snippet explicitly demonstrates f-string syntax (f\"...\") or the .join() method. A student with zero knowledge would not know that .join(fruits) omits the word 'and', nor would they confirm that the f-string syntax in Option B is valid for inserting list elements.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gaps are f-string interpolation syntax and the behavior of the string .join() method compared to manual indexing.", + "missing_concepts": [ + "f-string syntax and variable interpolation", + "String .join() method behavior", + "List indexing syntax (list[n])" + ], + "proposed_fix": "Add a snippet or reading material item that explicitly compares f-strings using indexing vs f-strings using .join() for list elements." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: f'Items: {items[0]}, {items[1]}' and comparing it to ', '.join(items).", + "why_helpful": "This directly addresses the core logic of the question: distinguishing between a simple join and specific formatting requirements like 'and' before the last item.", + "why_maybe_unnecessary": "If the student has access to a 'String Fundamentals' cheat sheet section not included in these exam snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:11:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})", + "b": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "c": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "d": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)" + }, + "correct": "d", + "explanation": "Option D constructs one aligned series for the local parts and one for the domains, then returns them in a DataFrame with the correct column names. The other options either overwrite values, build the wrong structure, or use the wrong field names.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Directly addresses the 'flexible number of arguments' concept (*args) required by the function signature in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains the syntax and behavior of functions accepting a flexible number of arguments (*args)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Contextualizes the concept of 'extracting' parts of a string (like a TLD or an email local part) from a formatted input." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Introduces Pandas Series, which are used in the correct answer (Option D) to build the final DataFrame." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers the *args requirement." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Covers the string parsing/extraction logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Covers the Pandas Series component." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Helps a student understand how to map keys to values (like column names to data lists) which is central to building the DataFrame." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover *args, the concept of string extraction, and the existence of Pandas Series. However, the exact syntax for splitting a string at a character (split('@')) and the constructor for a DataFrame from a dictionary of Series are not explicitly shown in the code samples, requiring the student to infer these patterns.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing explicit examples of the .split() method and the pd.DataFrame() constructor using a dictionary input.", + "missing_concepts": [ + "String splitting syntax (string.split('@'))", + "Pandas DataFrame construction from a dictionary of Series or lists", + "List comprehension for transforming a tuple of arguments" + ], + "proposed_fix": "Add a snippet demonstrating how to use split() to divide a string into components and another showing the creation of a multi-column DataFrame from a dictionary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: data = {'col1': [1, 2], 'col2': [3, 4]}; df = pd.DataFrame(data). Include a brief note on using .split() to break strings into list components.", + "why_helpful": "This directly bridges the gap between having extracted components and returning them as a structured DataFrame, which is the core task of the exam question.", + "why_maybe_unnecessary": "Option D uses pd.Series explicitly, so a student might guess the DataFrame structure if they understand Series, but the dictionary-to-DataFrame mapping is a common stumbling block.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:12:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "False\nTrue", + "c": "False\nFalse", + "d": "True\nFalse" + }, + "correct": "a", + "explanation": "The object is created with name 'John Smith', and because no gender argument is passed, the default value 'not specified' is used. Both comparisons therefore evaluate to True.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Directly demonstrates how default arguments work (num2=10, num3=20) when a function is called with fewer values than parameters, which is the exact logic needed to determine the 'gender' value in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explains the default parameter behavior which is critical for understanding why 'gender' defaults to 'not specified'." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the conceptual pattern for defining classes with attributes (name, mode) initialized during construction." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Shows equality comparison (==) logic, helping the student evaluate whether the print statements will result in True or False." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Covers the 'default value' logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Covers the 'class attribute initialization' pattern." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "By combining the OOP class structure from one snippet and the default argument mechanics from another, a student can clearly see that missing arguments trigger default values and that self.name is assigned from the first argument.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the concepts are covered across multiple snippets, there isn't a single example that explicitly shows the 'obj.attribute' access syntax alongside default arguments in a class context.", + "missing_concepts": [ + "explicit instance attribute access syntax (object.attribute)" + ], + "proposed_fix": "Add a snippet demonstrating a class with a default argument and a subsequent print of that attribute (e.g., p = Person('A'); print(p.age))." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: 'class User: def __init__(self, id, status=\"active\"): self.id = id; self.status = status; u = User(123); print(u.status == \"active\")'", + "why_helpful": "This merges OOP structure with default argument logic and attribute access in one clear example, mirroring the question's complexity.", + "why_maybe_unnecessary": "The student can technically deduce the answer by combining the 'Arguments' and 'OOP Fundamentals' snippets currently available.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:12:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original expression computes the number of days between January 10 and January 1, then adds 1, which yields 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-day-of-year", + "rationale": "It uses the exact logic from the question—subtracting January 1st from a date, accessing .days, and adding 1—to compute a day-of-year value, making the pattern directly recognizable." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Provides the structural template for the date arithmetic and explains the '+ 1' logic for inclusive day counting." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explicitly explains the mechanics: subtracting datetimes creates a timedelta, and .days returns the difference as an integer." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Shows the required imports and the syntax for creating datetime objects and performing subtraction." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Essential for the formula pattern." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Essential for understanding the data types involved (timedelta and integer attributes)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the day-of-year formula logic and the explanation of .days allows a student to calculate that the original code equals 10 and identify Option D as the equivalent result.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is clear, the 'strptime' function used in the question is not explicitly demonstrated in the code snippets, though it is inferable from the string content.", + "missing_concepts": [ + "Explicit demonstration of datetime.strptime() syntax and format codes like %Y/%m/%d" + ], + "proposed_fix": "Add a snippet demonstrating how to convert strings to datetime objects using strptime with common format codes." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'dt = datetime.strptime(\"2023/01/10\", \"%Y/%m/%d\")' with a comment explaining that %Y is year, %m is month, and %d is day.", + "why_helpful": "It removes any ambiguity for a non-Python user about how the string '2023/1/10' is being processed.", + "why_maybe_unnecessary": "Most students will correctly guess that '2023/1/10' represents January 10, 2023, without needing the technical definition of strptime.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:13:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df[['Player', 'Age']])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df.loc[:, 'Age'])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing in this form does not accept the tuple (1, 'Age') to select a single cell.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet is the most relevant as it explicitly discusses creating a new DataFrame by selecting specific columns for specific rows, which touches upon the mechanics of row/column indexing in Pandas." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Covers selecting specific columns and rows, helping the student understand valid selection patterns (relevant to options A and B)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a printed Pandas DataFrame with indices and columns, helping a zero-knowledge student visualize the 'df' described in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows basic column access like df['A'], which validates the use of string keys in brackets for column selection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using boolean masks and column lists for selection." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Contextualizes what a DataFrame looks like." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Confirms basic bracket notation for columns." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain the specific syntax rules of .loc vs. standard brackets, nor do they explicitly show that a tuple like [1, 'Age'] is invalid in standard brackets. A student with zero Python knowledge would not be able to confidently identify why Option D causes an error while Option A (nested brackets) does not.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The existing snippets do not define the difference between label-based indexing (.loc) and position-based or standard bracket indexing. Crucially, the 'standard bracket error' for multi-axis indexing is never mentioned.", + "missing_concepts": [ + "Pandas .loc syntax for simultaneous row and column selection", + "The invalidity of df[row, col] vs the validity of df.loc[row, col]", + "Double bracket syntax df[['col1', 'col2']] for selecting multiple columns" + ], + "proposed_fix": "Add a summary or rule-based snippet that contrasts valid selection methods (df['col'], df[['col1', 'col2']], df.loc[row, col]) with common syntax errors like df[row, col]." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas Selection Cheat Sheet. Content: To select one column: df['A']. To select multiple: df[['A', 'B']]. To select specific rows and columns by label: df.loc[row_index, 'column_name']. Note: Using df[index, 'column'] directly results in an error.", + "why_helpful": "It directly addresses the core logic required to distinguish between valid Pandas syntax and the error-inducing Option D in the exam question.", + "why_maybe_unnecessary": "If the goal is only to use existing exam questions as context, but since the current questions are truncated, they don't provide the syntax rules clearly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:13:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "animals methods", + "question": "You have the following definition for a class called Animals:\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs = True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin = True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "def walk():\n return sound if legs else 'Cannot walk!'\ndef swim():\n return sound if fin else 'Cannot swim!'", + "d": "def walk():\n if legs == True:\n return sound\n else:\n return 'Cannot walk!'\ndef swim():\n if fin == True:\n return sound\n else:\n return 'Cannot swim!'" + }, + "correct": "a", + "explanation": "Option A is the only choice that defines both instance methods with self and correctly returns self.sound when the corresponding boolean attribute is truthy, otherwise the required fallback string.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses adding a method (compare) to a class that involves logical conditions and attribute access, mirroring the structure required for walk() and swim()." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to structure a class method that performs logic based on instance attributes." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining a class and using the 'self' parameter in the constructor, which helps the student recognize that 'self' is a standard part of class definitions." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "While about functions, it demonstrates conditional logic, which is necessary to understand the 'if/else' requirements of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates instance method definition logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows class attribute initialization and the 'self' pattern." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Helps distinguish between proper comparison (==) and assignment (=) which is critical for identifying why option B is wrong." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets correctly point to the need for 'self' in methods and the use of 'self.attribute' for access. However, none of the snippets explicitly demonstrate the Python ternary operator (val if cond else other) used in the correct answer (Option A), nor do they explicitly warn against the common '=' vs '==' error in Option B for a student with zero Python knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing explicit examples of the ternary conditional operator and the distinction between instance methods vs. static/plain functions inside a class context.", + "missing_concepts": [ + "ternary conditional operator", + "comparison operator (==) vs assignment (=) in if-statements", + "explicit 'self' requirement for instance methods vs functions" + ], + "proposed_fix": "Add a snippet or AI-generated section that contrasts a plain function with a class method, specifically showing both 'if/else' and ternary syntax for returning values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Instance Methods and Conditional Returns' that shows: 1. A method using self. 2. A return statement using the 'X if condition else Y' syntax. 3. A warning that '=' cannot be used for comparison in 'if' statements.", + "why_helpful": "This would directly address the syntax found in the correct answer (ternary) and the syntax error in the most tempting distractor (Option B).", + "why_maybe_unnecessary": "If the student is very observant, they might infer 'self' from the constructor snippets, but the ternary operator is likely to be confusing.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:13:52Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "movie review methods", + "question": "You have the following definition for a class named Movie.\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute,\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and return the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segments will work as intended." + }, + "correct": "d", + "explanation": "Option A is broken because add_review uses list-plus-number syntax and compare immediately returns on the first loop iteration, so it never returns other.title when the other movie has the higher rating. Option B is also broken because add_review and rating are missing self and compare compares method objects instead of calling them.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "Directly demonstrates the correct implementation of a class with an add_review method using .append() and an average calculation method, which allows a student to identify the syntax errors in both options A and B." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Shows the correct way to append to a list attribute and structure methods with 'self', highlighting the flaws in both code segments." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Discusses the logic for a 'compare' method based on average review scores, providing the conceptual framework for the question's objective." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Reinforces the requirement for 'self' in method definitions and how attributes are initialized, which is a key error in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Covers appending to lists, method definitions with self, and average calculation logic." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippet 'manual-oop-state-compare' provides a nearly identical class structure (Book vs Movie). A student can see that adding to a list requires .append() (ruling out A's +=) and that methods must include 'self' (ruling out B).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective for this specific question because the AI-generated example perfectly mirrors the required methods.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:14:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "datetime weekly dates list", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "b": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "c": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "d": "This code segment will work as intended." + }, + "correct": "c", + "explanation": "After the first append, the newly added element is a formatted string, so on the next loop iteration the code tries to add a timedelta to a string instead of to a datetime object.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Mentions filtering 'non-integers', which introduces the concept that operations (like addition) are restricted to specific data types, mirroring the 'string vs datetime' conflict in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduces the principle of type-checking and the fact that functions/operations fail when applied to the wrong type (non-integers)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Discusses a function that takes a string and returns a 10-digit string, helpful for understanding string-to-string transformations." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates iterating through a list of strings and performing operations based on their properties (lengths)." + } + ], + "minimal_sufficient_snippets": [], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "No snippets cover the 'datetime' or 'timedelta' modules. Without knowing that 'strftime' converts a datetime object into a string, a student cannot deduce that the second iteration of the loop fails because it tries to add a timedelta to a string.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete gap regarding the 'datetime' module's specific methods and the resulting object types.", + "missing_concepts": [ + "The return type of datetime.strptime (datetime object) vs datetime.strftime (string)", + "The requirement that timedelta can only be added to datetime objects", + "How list elements can change types across iterations in a loop" + ], + "proposed_fix": "Add a core library snippet for Week 4/Datetime explaining the conversion cycle: String -> strptime -> Datetime -> strftime -> String." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Datetime and Timedelta Operations'. Key points: 1. datetime.strptime() returns a datetime object. 2. datetime.strftime() returns a string. 3. Adding a timedelta to a datetime object works; adding it to a string causes a TypeError.", + "why_helpful": "It explicitly provides the technical knowledge needed to evaluate Option C, which is the correct answer and the core 'trick' of the question.", + "why_maybe_unnecessary": "If this is a rare topic, but since it appears in final exams, it is high-value.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:14:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "pandas date column from day month year", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A correctly constructs datetime objects in year-month-day order from the three columns and then formats them into the requested DD-MM-YYYY strings.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the essential Pandas syntax for creating a new column ('C') by performing operations on existing columns ('A' and 'B')." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows how to assign a new column to a DataFrame based on existing column values, which is the high-level goal of the question." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a clear example of using zip() to iterate over multiple lists simultaneously, explaining the syntax used in the question's list comprehension." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces the concept of transforming Series values (using .map or similar), which provides context for the row-wise logic required here." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers the Pandas column creation boilerplate." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Explains the zip() function for parallel iteration." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the snippets explain the 'Pandas' and 'zip' parts of the code, they completely lack information on the 'datetime' module. A student cannot know that 'datetime(year, month, day)' is the correct argument order (distinguishing A from C) or that 'strftime' is used for formatting rather than 'strptime' (distinguishing A from B/D).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets cover general structural patterns but miss the specific library knowledge (datetime) required to differentiate the answers.", + "missing_concepts": [ + "datetime.datetime constructor argument order (Year, Month, Day)", + "Usage of strftime() for date-to-string formatting", + "Difference between strftime (format) and strptime (parse)" + ], + "proposed_fix": "Add a snippet demonstrating the creation of a datetime object from integers and its subsequent formatting into a string." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: 'Datetime Construction and Formatting'. Content: 'from datetime import datetime; # Order: Year, Month, Day; dt = datetime(2023, 5, 1); # Format to string; s = dt.strftime(\"%d-%m-%Y\") # Returns \"01-05-2023\"'.", + "why_helpful": "This provides the exact 'missing piece' regarding argument order and method selection (strftime) needed to solve the exam question.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:15:12Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "pandas above average salary", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 1000\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "None of the blocks of code will work as intended.", + "c": "Both blocks of code will work as intended.", + "d": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])" + }, + "correct": "a", + "explanation": "Option A correctly computes the mean salary, builds both required columns, and prints the full DataFrame filtered to rows where Above_average is True. Option D does not print the result in the required way because it filters only on Salary_difference > 0 rather than explicitly using the Above_average column requested in the specification.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This snippet introduces the core logic of calculating the difference between elements in a Series and their mean, which is central to both Operations 1 and 2." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Explains the concept of processing elements relative to the mean of a sequence (Series)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates vectorized column operations (df['C'] = df['A'] + df['B']), which validates the syntax used in Operation 2." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Covers boolean masks and selecting rows from a DataFrame based on indices/conditions, relevant for Operation 3." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Logic for mean and difference calculations." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Syntax for creating new columns via vectorized math." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Syntax for filtering DataFrames with boolean masks." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Shows the .map() method, helping the student distinguish why Option D (which uses .map()) might be syntactically valid but strategically different from Option A." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "Existing snippets cover column math and filtering logic, but none explicitly show the `.mean()` method or the specific `df[df['col'] == True]` print syntax. A student with zero knowledge would have to infer that `.mean()` is the standard way to get an average in Pandas.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide a strong foundation for column creation and filtering, but the specific Pandas aggregation method '.mean()' and the explicit syntax for boolean filtering in a print statement are missing.", + "missing_concepts": [ + "df['col'].mean() method", + "df[df['bool_col'] == True] filtering syntax" + ], + "proposed_fix": "Add a snippet demonstrating basic Pandas descriptive statistics (mean, sum) and how to use a boolean column to filter a DataFrame." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Pandas Aggregation and Filtering. 'To calculate the average of a column, use df[col].mean(). To filter a DataFrame to show only rows where a condition is met, use df[df[col] > value] or df[df[bool_col] == True].'", + "why_helpful": "It directly connects the 'average' requirement in the question to the '.mean()' method and explains the filtering syntax needed for Operation 3.", + "why_maybe_unnecessary": "The 'extra_practice' snippet mentions 'above average' logic for dictionaries, but Pandas-specific syntax is distinct enough to warrant its own entry.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:15:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "pandas lambda output", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "b": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "c": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15", + "d": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18" + }, + "correct": "d", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing C values 16, 17, and 18.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "It explicitly mentions that the .map() method allows applying a function to a Series, which is the fundamental mechanism being used in the code (df['A'].map(...))." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that .map() applies a function to each element of a Series." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the syntax for creating a new column 'C' by performing operations on other columns ('A' and 'B')." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes a scenario of creating a new Series where each element is based on a calculation involving the original element and an aggregate (the mean), similar to the lambda sum logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides the 'apply function' logic for .map()." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides the DataFrame column assignment syntax." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides context for element-wise operations involving aggregates." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets explain .map() and column creation, there is zero information on 'lambda' syntax or the '.sum()' aggregation method. A student wouldn't know that 'lambda x: ...' defines a function or that 'sum()' produces a single value (15) to be added to each 'x'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The main gaps are the definition and syntax of lambda functions and the behavior of pandas aggregation methods like .sum().", + "missing_concepts": [ + "lambda function syntax (lambda x: ...)", + "pandas .sum() aggregation behavior", + "The concept of using an aggregate value inside a row-wise map/apply function" + ], + "proposed_fix": "Add a key point or exam snippet that explains anonymous (lambda) functions and common pandas aggregations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Lambda Functions in Pandas. 'lambda x: expression' creates a small anonymous function where 'x' represents the value of each row/element when used with .map() or .apply(). Example: s.map(lambda x: x + 10).", + "why_helpful": "This is critical for understanding what the 'lambda' keyword does in the question code.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Pandas Aggregations. Methods like .sum(), .mean(), and .count() return a single number representing the total/average/count of the entire Series/column. Example: df['B'].sum() equals the sum of all values in column B.", + "why_helpful": "The student needs to know that df['B'].sum() is a constant value (15) in this context, not another Series.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:15:54Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q01", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q01", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_1", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "The three code lines evaluate to 2 * 3 == 6, 3 + 5 == 8, and 7 - 5 == 2, so each one is True. Therefore the correct choice is that all lines print True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This snippet contains the exact question, the specific list definition, and the step-by-step mathematical evaluation (e.g., 2 * 3 == 6) for each option, making it perfectly answerable without prior knowledge." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Identical to the exam question and provides the full numerical breakdown for options A, B, and C." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Provides the same question and evaluation logic, reinforcing the correct answer 'd'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "On its own, this snippet provides both the context and the solution logic required to verify the correct answer." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question being asked along with a detailed explanation of why each sub-expression evaluates to True.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover this specific question perfectly. However, if the question values were changed, the student would need a general rule for 2D indexing (row/column or list/tuple) and negative indexing.", + "missing_concepts": [ + "Negative indexing (e.g., x[-1] is the last element)", + "Nested indexing (e.g., x[0][1] accesses the second element of the first tuple)" + ], + "proposed_fix": "Add a foundational snippet explaining how x[i][j] works with both positive and negative integers for lists of tuples." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q02", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q02", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_1", + "question": "Executing the following program will produce an error. Why?\n\ndef power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)", + "options": { + "a": "Result is a local name that cannot be referenced outside of the function power.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "The function called power should not return the string 'The result of {} ** {} is: {}.'.format(num, factor, result), but the value of result." + }, + "correct": "a", + "explanation": "`result` is defined inside the function, so it has local scope. The line `print(result)` is outside the function and therefore cannot access that local variable.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "This snippet is an exact match for the exam question, identifying the specific function (power), the variable (result), and explaining that local scope prevents access from the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "Directly answers the specific question provided with identical variable and function names." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the conceptual definitions of local and global names, explaining that local names are only known inside the function." + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "Explains that a function leaves no traces and local names are gone after the function ends, reinforcing why the variable is inaccessible." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "Direct answer to the specific question." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Conceptual foundation for understanding scope." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact same question and a detailed explanation of the correct answer, as well as the underlying lecture theory.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent because the dataset includes the exact exam question being asked.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q03", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q03", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_3", + "question": "What will be printed by the following code segment?\n\ndef main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[None]", + "d": "[]" + }, + "correct": "b", + "explanation": "The function appends only elements whose type matches the type of `x`, which is `list`. Among the provided elements, only `[]` is itself a list, so the printed result is `[[]]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What will be printed by the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-3-w3-return-behavior" + ], + "evidence_topics": [ + "Return Behavior" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-3-w3-return-behavior" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "This snippet describes the exact logic of the question: checking if the type of an element matches the type of the input list and identifying that only '[]' satisfies this condition, resulting in '[[]]'." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Directly explains the type-matching logic and the specific behavior for the empty list within a list." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Essentially a duplicate of the best snippet, providing identical reasoning and the correct final answer for this specific code pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Reinforces the concept of type checking (e.g., distinguishing between int, float, and str) which helps a student understand the 'type(i) == type(x)' mechanic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "This single snippet provides the complete logic, the evaluation of the specific input elements, and the final output." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains two snippets that are near-exact matches for the logic and result of the question provided, explicitly explaining why '[[]]' is the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets perfectly cover the problem. No gaps identified for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:41Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q04", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q04", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_3", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\ndef main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10']", + "b": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10', '1 * 11 = 11']", + "c": "This code produces an error as there is a missing argument when calling main.", + "d": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')" + }, + "correct": "a", + "explanation": "When `main(1)` is called, `y` uses its default value `11`. The loop runs for `i` values 1 through 10, so it returns a list of ten multiplication strings from `1 * 1 = 1` through `1 * 10 = 10`.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "Suppose you have the following function, which takes two integers as arguments: What will be printed by the following line of code: print(main(1))", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "This snippet is a near-identical match to the target question, explicitly explaining that y defaults to 11 and describing the while loop's boundary condition." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Provides the exact logic and explanation for the specific code provided in the question." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Matches the question perfectly and explicitly notes the loop range (1 to 10) and the use of f-string formatting." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Reinforces the concept of default arguments with multiple examples, helping the student understand the general pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Contains the exact logic and answer required." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Two snippets in the candidate list are effectively the same question as the target, providing direct explanations for the default argument and loop behavior.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets provide direct answers to this specific question. No significant gaps exist for this particular problem.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q05", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q05", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "Functions Built-in", + "question": "Suppose you have a list called x, where:\n\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Both snippets produce [5, 4, 3, 2, 1]. The first removes duplicates and sorts the unique values in reverse order, and the second slices every second element from the reversed list.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "Suppose you have a list called x. Which of the following code segments will print the following list? [5, 4, 3, 2, 1]", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ], + "evidence_topics": [ + "Functions and Imports" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "This snippet is a direct match for the exam question. It explicitly explains that Option A uses set(x) to remove duplicates and sorted(..., reverse=True) to order them, and it begins to explain Option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Direct match that explains the removal of duplicates via sets and the reverse sorting logic." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Another direct match for the question, reinforcing the set and slicing explanation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides general context for list slicing syntax (e.g., [1::2]), which helps a student understand the mechanics of the slicing used in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Provides the direct answer and logic for both Option A and Option B of the specific question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact explanation for the question provided, identifying Option C as the correct answer and explaining the functions involved.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the snippets are direct matches, the text is truncated in the search results. A student with zero knowledge might struggle to fully verify the slicing logic ([::-2]) because the explanation is cut off mid-sentence.", + "missing_concepts": [ + "Complete step-by-step trace of the slice [::-2] on the provided list x." + ], + "proposed_fix": "Update the snippet text to ensure the explanation for the slicing operation is complete and easy to follow." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "proposal": "Ensure the text includes: 'Option B uses slicing [::-2], which starts from the end of the list and takes every second element, resulting in [5, 4, 3, 2, 1].'", + "why_helpful": "It allows a zero-knowledge student to manually verify the slicing result rather than just taking the snippet's word for it.", + "why_maybe_unnecessary": "The student may already be convinced by the explanation of Option A and the knowledge that 'Both' is an option.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:17:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q06", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q06", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "Function Flexible Argument", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "B sums the keyword argument values, which is exactly what the function should do. A incorrectly adds the keyword names, and C iterates over keys in a way that does not match the intended structure.", + "code_context": "def main(**kwargs):\n # Sum the values passed as keyword arguments" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments. For ex", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "This snippet contains the exact problem statement and example (main(apple=1.99...) returns 4.47) used in the question, providing direct context." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Exact match for the question prompt and example case." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Confirms that 'flexible number of keyword arguments' relates to dictionary-like key-value pairs, which helps bridge the concept to dictionary methods." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Shows another example of a function accepting a 'flexible number of arguments' to return a sum, reinforcing the pattern of using loops for totals." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Provides the problem context." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Explains the structure of keyword arguments as key-value pairs." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets provide the exact question text and identify that keyword arguments function as dictionaries, they do not explicitly explain the difference between .values(), .keys(), and .items() methods. A student with zero Python knowledge might struggle to choose between options B and C without knowing that .values() is required to access the numbers (prices).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets identify the problem but lack a technical definition of how to iterate over dictionary values vs keys.", + "missing_concepts": [ + "Difference between dict.values(), dict.keys(), and dict.items()", + "Implicit conversion of **kwargs into a dictionary inside the function" + ], + "proposed_fix": "Add a summary snippet or code example explaining that **kwargs creates a dictionary, and summing values requires iterating over .values()." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-6-w3-arguments", + "proposal": "Append the correct code solution and a brief explanation: 'Use **kwargs to capture keyword arguments as a dictionary; use kwargs.values() to iterate over and sum only the values (prices).'", + "why_helpful": "It directly answers the 'how' for a student who recognizes the problem but doesn't know the specific dictionary method names.", + "why_maybe_unnecessary": "The student might infer it if they have a general 'Dictionary Methods' snippet elsewhere, but specialized **kwargs help is better.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:17:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q07", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q07", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries Comprehension", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {len: word for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to its length. The other options either reverse the key/value order or use invalid comprehension logic.", + "code_context": "words = ['example', 'python', 'exam']" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 7, + "question_summary": "Assume you already have a list of strings called words. You need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are the", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet is a verbatim match for the exam question, featuring the exact variable names (words, word_lengths) and the specific task of mapping strings to their lengths." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Directly identifies the specific problem context and provides the identical prompt." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Describes the general logic for creating a dictionary where keys are list elements and values are character counts (lengths), identifying it as a 'standard dictionary comprehension'." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows a similar task (creating person_dict from names/ages) which helps reinforce the key:value construction pattern in dictionaries." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides the exact context and problem statement." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Provides the conceptual explanation of the correct mechanism (dictionary comprehension for lengths)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of a verbatim question match (Snippet 1) and a conceptual match for the 'element-to-length' mapping logic (Snippet 16) allows a student to identify the correct code pattern even without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the snippets cover the problem, the search text in the candidate snippets is truncated, which might hide the actual code for the correct option 'c'.", + "missing_concepts": [ + "explicit syntax demonstration of {k: len(k) for k in list}" + ], + "proposed_fix": "Enrich the dictionary comprehension snippets to explicitly show the {key: value for item in iterable} syntax in the search_text preview." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "proposal": "Update the search_text to include the full solution code for option C: word_lengths = {word: len(word) for word in words}.", + "why_helpful": "The current snippet cuts off at 'Option A is a vali', which might lead a student to think A is the answer, even though the provided question says C is correct.", + "why_maybe_unnecessary": "Snippet 16 provides the conceptual backing, but clarity is always better.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:18:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q08", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q08", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades:\n- The students list contains strings representing the names of students.\n- The grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears, which matches the requested dictionary. B stores lists of students per grade, so it does not produce counts.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet is a near-identical match to the question being asked, providing the exact context, example data, and even confirming 'Option a' as the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Identical question and answer match." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows a similar pattern of creating a dictionary from a list and validates a specific code segment as correct, helping the student understand dictionary construction." + }, + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the logic of adding keys to a dictionary and incrementing values (e.g., adding shirts), which is the core logic of the correct answer." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Provides the direct answer to the specific question." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Introduces the concept of using two parallel lists (names and ages) to build a dictionary, which helps differentiate why the 'zip' approach in option b might be used but is incorrect for counting." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question and its solution. Even without prior knowledge, a student can simply match the 'grade_counts' requirement to the snippet providing 'Option a'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is directly provided in one snippet, the underlying logic of the 'initialize if missing, then increment' pattern is not explicitly explained as a general concept in the snippets.", + "missing_concepts": [ + "The 'if key not in dictionary' pattern for counting", + "Difference between assignment (=) and incrementing (+=) in a dictionary context" + ], + "proposed_fix": "Add a conceptual snippet or a lecture-based 'Key Point' that explains the standard algorithm for counting occurrences using a dictionary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Key Point' snippet titled 'Counting with Dictionaries' that explains: To count items, check if the item is a key. If not, set it to 0. Then, increment by 1.", + "why_helpful": "This would allow a student to solve the problem by understanding the logic rather than just finding the identical question in the database.", + "why_maybe_unnecessary": "The direct match snippet already ensures the student can answer the specific exam question correctly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:18:27Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q09", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q09", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the correct result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text, the same dictionary (math_scores), and the same objective (finding scores above average)." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Identical question and data structure; directly maps to the exam problem." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates calculating an average from a dictionary of numerical values (monthly_sales)." + }, + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Shows how to iterate through a dictionary (employee_ratings) to find specific values based on a condition." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Contains the specific logic and variable names used in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippet 'exam-extra_practice-4-w2-dictionaries-and-mappings' is an exact match for the exam question, providing the student with the direct context needed to identify the correct code segments.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide an exact match for the question logic. The only potential gap is the truncated explanation in the snippet which mentions an indentation error in Option A, whereas the question claims both work.", + "missing_concepts": [], + "proposed_fix": "None required for answerability, but cleaning up the snippet text to ensure the explanation matches the 'Correct: C' logic would reduce confusion." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "proposal": "Ensure the 'search_text' includes the full code for options a and b and clarifies why both work, matching the provided question explanation.", + "why_helpful": "The current snippet cut-off mentions an indentation error for Option A, which contradicts the 'Correct: C' (both work) answer in the exam question. Aligning these prevents student confusion.", + "why_maybe_unnecessary": "The student can likely infer the logic from the code patterns even if the explanation is cut off.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:18:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q10", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q10", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how a list comprehension with an 'if' clause works as a filter, which is the core structural logic of the question's code segment." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the filtering logic of list comprehensions ([x for x in list if condition])." + }, + { + "item_id": "kp-2", + "rationale": "Clarifies that methods (like .islower()) are functions attached to objects (like strings) and explains their general behavior." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Provides the blueprint for interpreting the list comprehension syntax and the filtering process." + }, + { + "item_id": "kp-2", + "rationale": "Helps the student identify '.islower()' as a method being called on the character objects." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain the list comprehension's filtering logic, but none of them define the '.islower()' method or its behavior regarding punctuation and whitespace. A student might guess 'islower' means 'lowercase letter', but they wouldn't be certain how it handles commas or spaces without a specific definition.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student can understand the 'how' (filtering via comprehension) but not the 'what' (the specific criteria of islower).", + "missing_concepts": [ + "Definition of the .islower() string method", + "Behavior of .islower() on non-alphabetic characters (spaces, punctuation)" + ], + "proposed_fix": "Add a key point or reference snippet covering 'Boolean String Methods' (islower, isupper, isdigit, isalpha) and their return values for non-letters." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Boolean String Methods. Methods like .islower(), .isupper(), and .isdigit() return True only if the string contains at least one character and all characters meet the criteria. Importantly, .islower() returns False for spaces, punctuation, and numbers as they are not lowercase letters.", + "why_helpful": "It provides the missing definition needed to definitively choose option (a) over (b) or (c) by clarifying that symbols and spaces are excluded.", + "why_maybe_unnecessary": "A student might intuitively guess that 'islower' only applies to letters, but 'zero prior knowledge' requires explicit confirmation.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:19:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q11", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q11", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "It demonstrates the use of the `.append()` method, which is the mechanism used to build the result list in the question code." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows list initialization and the `.append()` method." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains the `print()` function, which is necessary to understand how the final result is displayed." + }, + { + "item_id": "aiq-2", + "rationale": "Reinforces the concept of list mutation through methods like `.append()`." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Explains .append()" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains print()" + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While 'append' and 'print' are covered, the two most critical concepts required to solve this specific problem—the `zip()` function (pairing elements from two lists) and the `//` operator (floor division)—are completely absent from the candidate snippets. A student with zero Python knowledge would not know what 'zip' does or that '//' rounds down to the nearest integer.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to explain the iterative pairing logic of zip and the mathematical behavior of floor division.", + "missing_concepts": [ + "zip() function behavior", + "// (floor division) operator", + "unpacking multiple variables in a for loop (for a, b in ...)" + ], + "proposed_fix": "Add a snippet or common question entry that specifically explains how `zip` works with two lists and clarifies the difference between `/` and `//`." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a common question snippet: 'How do zip() and floor division (//) work?'. Content: `zip(list1, list2)` pairs elements by index: (list1[0], list2[0]), (list1[1], list2[1]). `//` is floor division, which divides and rounds down to the whole number (e.g., 5 // 2 = 2).", + "why_helpful": "Directly addresses the two primary 'black boxes' in the question for a non-Python user.", + "why_maybe_unnecessary": "Basic math might be assumed, but zip is definitely a specific Python syntax that needs explanation.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:19:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q12", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q12", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "This snippet is a near-exact match for the question, containing the same list, target value, and explanations for how specific slicing parameters (start -1, step -2) produce the requested result." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Directly addresses the list slicing logic for the specific numbers and step values used in the question." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Explains the [::-1] slicing syntax as a method to reverse a list, which is critical for evaluating options A, B, and C." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Provides a clear example of the [start:stop:step] notation (specifically step) within the 'Sequences and Access' topic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Provides the core logic for the specific problem." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Clarifies the reversal syntax." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-extra_practice-6-w1-sequences-and-access' contains the exact logic for slicing with negative steps and starting points on this specific list, making the answer derivable even without prior knowledge if the student matches the logic.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is present, there is a lack of explicit documentation on 'nested slicing' (applying a second slice to the result of a first slice), which is required for options A and C.", + "missing_concepts": [ + "nested slicing execution order", + "implicit start/stop indices when step is negative" + ], + "proposed_fix": "Add a dedicated subtopic or tip explaining that in 'list[a:b:c][d:e:f]', the first slice is computed entirely before the second slice is applied to that resulting subset." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-extra_practice-6-w1-sequences-and-access", + "proposal": "Expand the search text/explanation to explicitly define why option A ([::-2][::-1]) results in [2, 4, 6, 8, 10] (it reverses the reversed slice).", + "why_helpful": "The current snippet text is truncated and might confuse students if the option letters (a, b, c, d) are shuffled in the exam.", + "why_maybe_unnecessary": "The logic 'starts at -1, step -2' is already present and might be enough for a smart student to eliminate options.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:19:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q13", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q13", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "string - find - 3", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", so only the second occurrence remains replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates string slicing syntax (`alphabet[1::2]`), which is the foundational concept needed to understand the code in Option A." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of using square bracket notation to slice a string variable, helping a user interpret the syntax used in Option A." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Describes a problem involving string formatting and removing separators (dashes) from a string, which conceptually relates to the string replacement task." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Involves extracting specific substrings from a URL, a task that typically requires finding indices and slicing, mirroring the logic in Option A." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Example of string slicing syntax." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Context for string manipulation/formatting." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Context for substring extraction." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the question provides a helpful hint for the find() method, no snippet explains the count parameter in string.replace() (required for Option B) or basic [start:end] slicing and string concatenation (required for Option A).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus heavily on dictionaries and OOP, leaving a significant gap in foundational string manipulation methods and slicing syntax.", + "missing_concepts": [ + "The optional 'count' argument in string.replace(old, new, count)", + "Basic string slicing syntax [start:end]", + "String concatenation using the '+' operator" + ], + "proposed_fix": "Add a technical reference snippet or a lecture example that explicitly covers the 'replace' method with counts and demonstrates how to rebuild a string using slices and '+', as this is a common exam pattern." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Common String Operations' showing: 1. text.replace('a', 'b', 1) to replace only the first occurrence; 2. index-based slicing like text[:5] and text[10:]; 3. concatenating slices with +.", + "why_helpful": "This would allow a student to verify both Option A (slicing) and Option B (replace with count) without prior knowledge.", + "why_maybe_unnecessary": "The question hints at find(), but find() alone isn't enough to understand the replacement logic in the options.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:20:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q14", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q14", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "string - fstring - 3", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the required sentence exactly, including the word \"and\" before the final fruit. Option A joins the list without \"and\", so it does not produce the exact requested output.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves printing a specific string template with variable placeholders ('[NAME] has received a grade of [GRADE]'), which is the closest conceptual match to the string formatting required for f-strings." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Illustrates the requirement of matching a specific output string format using variables." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows the use of square brackets `[]` for sequence access (slicing), which hints at the indexing syntax used in Option B." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides context for string manipulation in Python, though it focuses on different methods (.map, .split)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Closest match for string template logic." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Introduces sequence bracket syntax." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The candidate snippets completely lack the foundational concepts needed: f-string syntax (f'{}'), basic list indexing (list[i]), and the behavior of the .join() method. A student without prior knowledge would be unable to distinguish why Option B is correct and Option A is not (specifically regarding the inclusion of 'and').", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a total absence of basic string formatting and list indexing documentation in the current selection.", + "missing_concepts": [ + "f-string syntax and variable interpolation", + "List element access via integer indexing (0, 1, 2)", + "The exact behavior of '.join()' (specifically that it does not handle the Oxford comma/last element differently)" + ], + "proposed_fix": "Add fundamental snippets covering f-strings from Week 1 or Week 4, and list indexing examples from Week 1." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining f-strings: f'Hello {name}' replaces {name} with the variable value.", + "why_helpful": "Essential to understand how both Option A and Option B work.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining list indexing: fruits[0] is the first item, fruits[1] is the second.", + "why_helpful": "Necessary to decode what Option B is actually doing.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining ', '.join(list): Result is 'item1, item2, item3' with no 'and'.", + "why_helpful": "Allows the student to realize Option A is a distractor that produces a different string than requested.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:20:49Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q15", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q15", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "string - operations - 3", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)", + "b": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "c": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "d": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})" + }, + "correct": "a", + "explanation": "Option A builds aligned pandas Series for the local parts and domains, then returns them in a DataFrame with the correct column names. The other options either swap fields, overwrite values, or construct the DataFrame incorrectly.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains how to use the .split() method to extract specific parts of a string based on a separator (like ';' or '@'), which is the core logic needed to extract 'local' and 'domain' parts from email addresses." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly addresses string splitting and part extraction in a pandas/data context." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains the syntax for a function that accepts a flexible number of arguments (*args), which is required for the main() function signature." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides context on Pandas Series, which are used in the correct answer (Option A) to construct the columns of the DataFrame." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides the string splitting logic." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Provides the *args flexible argument syntax." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides the Pandas Series context used in the solution." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain *args and string splitting, which are the hardest parts. However, a student with zero knowledge might still struggle to understand how to combine list comprehensions with dictionary keys and pd.DataFrame construction into the exact format of Option A.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is a lack of an example showing the construction of a DataFrame from a dictionary of lists or Series, especially when those lists are created via list comprehensions.", + "missing_concepts": [ + "DataFrame construction from a dictionary of Series", + "List comprehension syntax for processing function arguments (*args)" + ], + "proposed_fix": "Add a snippet that demonstrates creating a DataFrame from a dictionary where the values are lists generated by splitting strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'df = pd.DataFrame({\"part1\": [x.split(\"-\")[0] for x in args], \"part2\": [x.split(\"-\")[1] for x in args]})'", + "why_helpful": "This pattern perfectly matches the logic required in the question (Option A), showing how to map processed strings into DataFrame columns.", + "why_maybe_unnecessary": "Students might be able to piece this together if they understand Dictionaries and Series separately, but a combined example is much clearer for beginners.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:21:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q16", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q16", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Easy_1", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "True\nFalse", + "c": "False\nTrue", + "d": "False\nFalse" + }, + "correct": "a", + "explanation": "The name comparison is true because the object stores 'John Smith', and the gender comparison is also true because the default value 'not specified' is used when no gender is provided.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly demonstrates how default arguments work when a function is called with fewer arguments than parameters (e.g., add_numbers(5, 15)), which is the core logic required to understand why 'gender' becomes 'not specified'." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explains default parameter behavior, allowing the student to deduce the value of the 'gender' attribute." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Shows the syntax for defining a class with 'name' and 'mode' attributes initialized in the constructor, which mirrors the Employee class structure." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Demonstrates the use of the equality operator (==) and the resulting boolean output (True/False) when printed." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Handles the default argument logic for the missing 'gender' value." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Handles the OOP syntax and attribute assignment (self.name = name)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the OOP structure snippet and the default arguments snippet provides all the mechanical rules needed to trace the code execution accurately.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover class structure and default arguments separately. While sufficient, a single example combining both would reduce the cognitive load for a novice.", + "missing_concepts": [ + "Explicit link between __init__ parameters and attribute access (self.attribute)." + ], + "proposed_fix": "Add a snippet or edit an existing OOP one to include a default parameter in the __init__ method." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "proposal": "Update the search_text to show a snippet of the code for the Vehicle class, specifically including a default value for the 'mode' attribute (e.g., mode='land').", + "why_helpful": "It would show the exact pattern used in the question (OOP + Default Arg) in a single visual context.", + "why_maybe_unnecessary": "The logic can currently be synthesized by looking at two different snippets.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:21:43Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q17", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q17", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_2", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original code computes the difference in days between January 10 and January 1, then adds 1, yielding 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-day-of-year", + "rationale": "This snippet provides the exact logic used in the question: subtracting January 1st from a date and adding 1 to calculate the day count. It explicitly explains that adding 1 makes Jan 1st 'day 1'." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Shows the '(date - start_date).days + 1' pattern and explains the logic for day numbering." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explains the technical mechanism: subtracting datetimes creates a timedelta, and .days retrieves the integer difference." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Provides the general rule for datetime arithmetic and mentions that subtracting datetimes creates timedeltas." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Matches the mathematical logic of the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explains the data types and attributes (.days) involved." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the 'manual-datetime-day-of-year' example and the 'exam-intro' explanation covers both the logic (+1 offset) and the syntax (.days attribute). A student can intuitively map '2023/1/10' to Jan 10th even without knowing strptime details.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets explain the arithmetic and the result type well, but there is no explicit explanation of strptime format codes like %Y, %m, or %d.", + "missing_concepts": [ + "datetime.strptime format codes" + ], + "proposed_fix": "Add a snippet explaining common datetime format codes (%Y, %m, %d, %H, %M, %S) to ensure students can accurately parse strings into dates." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String to Datetime Parsing (strptime)\nContent: datetime.strptime(string, format) converts text to a date object. \nFormat codes: %Y (4-digit year), %m (month 01-12), %d (day 01-31), %H (hour), %M (minute).\nExample: datetime.strptime('2023/1/10', '%Y/%m/%d') creates a date for Jan 10, 2023.", + "why_helpful": "It removes the small inferential leap required to understand that strptime is creating a date for January 10th based on the provided format string.", + "why_maybe_unnecessary": "Most students will guess the meaning of '%Y/%m/%d' correctly given the sample string '2023/1/10'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:22:06Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q18", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q18", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "pandas - easy - 3", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df.loc[:, 'Age'])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df[['Player', 'Age']])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing does not accept the tuple (1, 'Age') in this form.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This is the only snippet that explicitly mentions 'Inspecting and Selecting Data' and discusses selecting columns using a list (e.g., ['B']), which relates to the logic in options B and C." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Discusses row/column selection logic, providing context for how DataFrames are filtered." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Identifies the core topic of the question (Inspecting and Selecting Data) and shows a sample DataFrame structure." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows basic column access (df['A'], df['B']) which helps a student understand the standard bracket syntax used in Option C." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides the closest conceptual match for DataFrame selection patterns." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates standard column selection which validates part of the question's logic." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets demonstrate the use of '.loc' (Options A and B) or explain that standard brackets 'df[row, col]' are invalid for DataFrames. While Item 12 mentions selection, the actual code syntax is not visible in the snippet text, making it impossible for a zero-knowledge student to distinguish between valid and invalid indexing methods.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a clear contrast between basic indexing (df['col']) and label-based indexing (df.loc[row, col]).", + "missing_concepts": [ + "pandas .loc syntax", + "difference between df[] and df.loc[]", + "KeyError/TypeError for multi-axis indexing in standard brackets" + ], + "proposed_fix": "Add a summary card or snippet that explicitly states: 'Use df.loc[row, col] for simultaneous row/column selection; standard brackets df[...] only accept column names, lists of columns, or slices.'" + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Pandas Indexing Rules' snippet showing: 1. df['ColName'] (Valid), 2. df[['C1', 'C2']] (Valid), 3. df.loc[index, 'Col'] (Valid), 4. df[index, 'Col'] (Error).", + "why_helpful": "It directly maps to the four options in the question, allowing a student to identify the error through pattern matching.", + "why_maybe_unnecessary": "If a student already knows dictionary-like indexing, they might guess D is wrong, but .loc (A/B) would still be confusing.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:22:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q19", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q19", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Function_1", + "question": "You have the following definition for a class called Animals:\n\nclass Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ...\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs == True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin == True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "c", + "explanation": "Both shown method implementations use the instance attributes to return the animal's sound when the relevant boolean attribute is present and the required fallback message otherwise.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly describes writing a method that uses instance attributes to return a result based on logic (comparing scores), which is the core task of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows logic inside a class method using instance data." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Provides the basic template for defining a class with attributes, which helps a novice understand the structure of the provided code context." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Demonstrates simple if/else branching logic, which is necessary for evaluating option (b)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates the concept of a method accessing its own attributes to perform a check." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Shows how attributes are initialized and mapped to 'self', explaining the existence of self.legs/self.fin." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Explains standard conditional logic (if/else)." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain class structure, attributes, and basic 'if/else' logic. However, they do not explain the 'ternary operator' syntax used in option (a) (x if condition else y) nor the fact that 'if self.legs' is equivalent to 'if self.legs == True' for boolean values, which is critical for choosing 'c' over just 'b'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing explanations for Python-specific conditional expressions (ternary operators) and truthy/falsy evaluation of booleans.", + "missing_concepts": [ + "Ternary operator syntax (return x if condition else y)", + "Boolean evaluation (if x vs if x == True)", + "Explicit 'self' attribute access syntax explanation" + ], + "proposed_fix": "Add a snippet from the 'Conditions' or 'OOP' week that explicitly shows both standard if/else and the conditional expression version of the same logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Conditional Expressions vs Statements' showing: 'return \"Yes\" if check else \"No\"' is equivalent to 'if check: return \"Yes\" else: return \"No\"'.", + "why_helpful": "Directly enables a student to recognize that both option (a) and (b) in the question are functionally identical.", + "why_maybe_unnecessary": "A student might guess if they understand standard 'if' blocks, but they won't be certain.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining 'self' as a reference to the current instance, used to access attributes defined in __init__.", + "why_helpful": "Ensures the student understands that 'self.legs' refers to the value passed during 'cat = Animals(..., legs=True)'.", + "why_maybe_unnecessary": "The existing 'Vehicle' class snippet hints at this, but doesn't explain the lookup mechanism within a method.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:22:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q20", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q20", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Hard_3", + "question": "You have the following definition for a class named Movie.\n\nclass Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ...\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute.\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and returns the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "d", + "explanation": "The first code segment is broken because it tries to add an integer directly to a list and its compare logic cannot return the other movie's title correctly. The second code segment omits self where needed and compares method objects instead of method results.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This snippet provides a near-identical class structure (Book vs Movie) and demonstrates the correct implementation of add_review (using .append) and average/rating. It directly exposes the syntax errors in Option A (using += on a list) and Option B (missing self)." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Demonstrates proper method definition with self, attribute access, and list appending, which are the main points of failure in the options." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "While textual, it describes a 'compare' method logic for objects, helping the student understand the conceptual goal of the method." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Reinforces the pattern of initializing multiple attributes using self in the constructor." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Covers 2 out of 3 methods and demonstrates self-parameters and list mutation." + } + ], + "answerability": { + "status": "partial", + "confidence": "high", + "rationale": "The student can identify why Option A is wrong (list += int error vs .append) and why Option B is wrong (missing self in method signatures) by looking at 'manual-oop-state-compare'. However, the subtle error in Option B (comparing methods instead of calling them with brackets) is not explicitly contrasted in any snippet.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No snippet explicitly demonstrates the difference between a method reference and a method call (e.g., self.rating vs self.rating()), nor does any snippet show one instance calling a method on another instance (other.rating()).", + "missing_concepts": [ + "method calls vs method references (brackets usage)", + "inter-object method calls (other.method())" + ], + "proposed_fix": "Add a comparison method to the Book example in 'manual-oop-state-compare' that uses 'other.average()' to demonstrate proper calling syntax." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "manual-oop-state-compare", + "proposal": "Add a compare method: def is_better(self, other): return self.average() > other.average()", + "why_helpful": "This would show the necessity of using brackets () when calling a method on both self and another object, directly addressing the 'd' answer rationale.", + "why_maybe_unnecessary": "The existing snippet already helps eliminate A and B based on the self parameter and list mutation syntax.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:23:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q21", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q21", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_1", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "b": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "c": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "d": "This code segment will work as intended." + }, + "correct": "b", + "explanation": "After the first append inside the loop, the list contains formatted date strings. On the next iteration the code tries to add a timedelta to that string, which is not allowed.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduces the concept of type-checking and filtering (integers vs strings/floats), which helps establish that operations in Python are sensitive to whether data is a string or a numeric object." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Highlights the distinction between strings and numeric types during calculations, which is conceptually similar to the datetime/string conflict." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Provides an example of a function iterating through a list and processing elements, which helps a student understand the basic execution flow of the question's code." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Shows a list containing dictionaries (complex objects), which reinforces the idea that lists can store different types of data simultaneously." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Necessary to hint at type-dependent failures." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The question requires specific knowledge of the 'datetime' module: 1) That strptime returns a datetime object, 2) That strftime returns a string, and 3) That timedelta cannot be added to a string. None of the provided snippets mention datetime, strftime, or the specific rules of timedelta arithmetic. A student with zero knowledge would not realize that the list elements change from objects to strings after the first iteration.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets focus on general logic and basic data types, but the question hinges on the specific behavior of the datetime library and the 'gotcha' of mixing formatted strings with datetime arithmetic.", + "missing_concepts": [ + "The 'datetime' module and 'timedelta' usage", + "The difference between a datetime object (computable) and its string representation (non-computable)", + "The specific return types of .strftime() and .strptime()" + ], + "proposed_fix": "Add a snippet or card explaining that formatting functions like strftime() produce strings, which prevents further mathematical operations (like adding a timedelta) that require actual datetime objects." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card for 'Datetime and Timedelta Arithmetic'. Explicitly state: 'datetime.strptime()' returns an object you can do math with. 'obj.strftime()' returns a STRING for display. You CANNOT add a timedelta to a string. Example: (date_obj + timedelta) works, but (date_string + timedelta) fails.", + "why_helpful": "This directly explains the 'b' distractor in the question, which is the correct answer.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:23:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q22", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q22", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_3", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas module is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A builds real datetime objects using year, month, and day in the correct order and then formats each one as DD-MM-YYYY.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which is the first step of the required operation." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows how to create a new column in a DataFrame by performing operations on existing columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Illustrates string manipulation within a pandas Series, which helps the student understand that column values can be transformed into new string formats." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Though focused on dictionaries, it introduces the concept of processing multiple lists/columns together (names and ages), similar to the zip requirement in the datetime question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Confirms the df['NewColumn'] = ... syntax used in all options." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides context for element-wise string transformation in pandas." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Relates to the concept of iterating through multiple parallel data sources (zip)." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the 'datetime' module, the 'datetime()' constructor (specifically the order of year, month, day), or the 'strftime' method for string formatting. A student with zero knowledge would have no way to distinguish between Option A (correct order) and Option C (incorrect order).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets cover basic Pandas column creation but entirely miss the core 'Datetime' and 'String Formatting' requirements of this 'Hard' level question.", + "missing_concepts": [ + "datetime.datetime constructor argument order (year, month, day)", + "datetime.strftime() method and format codes (e.g., %d, %m, %Y)", + "zip() function for parallel iteration over multiple columns", + "list comprehensions for creating Series" + ], + "proposed_fix": "Add a snippet from a lecture or manual entry that explicitly shows creating a datetime object and formatting it with strftime." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Datetime Formatting' that shows: from datetime import datetime; dt = datetime(2023, 5, 1); print(dt.strftime('%d-%m-%Y'))", + "why_helpful": "This provides the missing link for the student to understand the constructor order and the formatting codes required to pick Option A over C or B.", + "why_maybe_unnecessary": "Only if the student is expected to already know the datetime library, but the prompt specifies 'zero prior knowledge'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:24:11Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q23", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q23", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "pandas - hard - 3", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 100\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])", + "c": "Both blocks of code will work as intended.", + "d": "None of the blocks of code will work as intended." + }, + "correct": "c", + "explanation": "Both code blocks compute the rounded mean salary, derive an above-average indicator, compute salary differences from that mean, and filter the rows with positive differences.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This snippet directly addresses the logic of calculating the mean of a Series and performing arithmetic operations (difference) on each element, which is central to Operations 1 and 2." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Covers the 'mean' calculation and Series-wide arithmetic (subtraction), which is key for finding the salary difference." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the fundamental syntax for creating a new column in a DataFrame based on operations between other columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces the `.map()` method, which is used in Option B to apply conditional logic or transformations to each row." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Explains mean and element-wise differences." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows column creation syntax (df['C'] = ...)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Shows usage of .map() for applying functions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a 'boolean mask' to select specific rows, which helps with Operation 3's filtering logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover mean calculation, column creation, and the map method. However, they do not explicitly show the 'lambda x: ...' syntax with an if-else inside, nor do they clearly demonstrate the 'df[df['col'] == value]' filtering syntax in a way that a student with zero Python knowledge could confidently reconstruct.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing clear examples of boolean indexing for filtering DataFrames and the specific use of ternary operators within lambdas/maps.", + "missing_concepts": [ + "Boolean indexing (df[condition])", + "Lambda functions with conditional logic (if-else)", + "List comprehension for creating Series" + ], + "proposed_fix": "Add a snippet demonstrating how to filter a DataFrame using a boolean condition and another showing a map/lambda with an if-else statement." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Pandas Boolean Filtering' showing: df_filtered = df[df['Salary'] > 50000].", + "why_helpful": "This directly enables the student to understand the syntax for Operation 3.", + "why_maybe_unnecessary": "Snippet exam-intro_python_sample_final_24_25-6 mentions boolean masks, but the code snippet in the preview is cut off.", + "recommended_direction": "add_this" + }, + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "proposal": "Ensure the example code includes a lambda with a condition, e.g., s.map(lambda x: 'High' if x > 10 else 'Low').", + "why_helpful": "It validates the syntax used in Option B of the question.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:24:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q24", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q24", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "pandas - lambda - 3", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18", + "b": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "c": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "d": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15" + }, + "correct": "a", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing 16, 17, and 18 in column C.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explicitly mentions that the .map() method allows applying a function to each element in a Series, which is the core mechanic of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains the purpose of .map() for applying functions to Series values." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides the structural context of creating a new column 'C' from existing columns 'A' and 'B' in a DataFrame." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Shows operations involving a Series and an aggregate value (like mean, similar to sum) for each element." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces .map()." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Introduces column derivation (A, B -> C)." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Contextualizes calculations involving the whole Series and its properties." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain .map() and the context of creating a new column, but they do not explicitly define the 'lambda' syntax or the '.sum()' method for a student with zero prior knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "While the general pandas context and .map() functionality are touched upon, the specific syntax of anonymous 'lambda' functions and the behavior of '.sum()' on a column are missing.", + "missing_concepts": [ + "lambda functions (anonymous functions)", + "Series.sum() method for aggregation" + ], + "proposed_fix": "Add a snippet or key point that demonstrates a lambda function adding a scalar value (like a sum) to each element of a column." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a key point (e.g., kp-pandas-lambda-agg) that shows: 'df['C'] = df['A'].map(lambda x: x + constant)' and explains that 'lambda x' represents each value in column 'A'.", + "why_helpful": "This bridge is necessary to understand how the lambda variable 'x' interacts with the result of 'df['B'].sum()'.", + "why_maybe_unnecessary": "If the student already understands functions and basic aggregation, the existing .map() snippet might be enough to guess.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:25:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q01", + "question_id": "sample-final-plus-answers-q01", + "exam_id": "sample-final-plus-answers", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "vehicle class defaults", + "question": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation.\nThe name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string \"land\".\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A correctly defines the constructor with `self`, stores both attributes on the instance, and gives `vehicle_mode` the default value `\"land\"`.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any st", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 1, + "question_summary": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any st", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-init-default", + "rationale": "Directly explains the concept of optional constructor arguments with default values and provides a code pattern nearly identical to the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Explains the specific syntax for default values in __init__ which is the core of the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Reinforces the problem context by providing the exact question text from a past exam." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides redundant but helpful context for the specific OOP scenario described." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Contains both the conceptual explanation and the syntax needed to identify Option A as the correct implementation." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippet 'manual-init-default' explicitly covers the mechanics of default values in class constructors and even uses the same variable names (vehicle_mode='land'), making it easy for a student to match with the correct option.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets cover the primary challenge (default values). However, a beginner might still struggle to understand why 'self' is required or why attributes must be assigned to 'self' rather than just used as local variables.", + "missing_concepts": [ + "Explicit role of 'self' in instance attribute assignment vs local variables" + ], + "proposed_fix": "Add a snippet explaining that 'self.attribute = value' is necessary to persist data on the object, which would help distinguish Option A from Option D." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Instance Attributes and 'self'. Content: 'To make an attribute available on an object (like my_car.name), you must assign it to self inside the __init__ method (e.g., self.name = vehicle_name). Without self, the variable only exists temporarily during creation.'", + "why_helpful": "Provides a clear reason to choose Option A over Option D, as Option D defines variables without self.", + "why_maybe_unnecessary": "Option A is already the most likely choice for a student matching the default value syntax provided in 'manual-init-default'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:25:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q02", + "question_id": "sample-final-plus-answers-q02", + "exam_id": "sample-final-plus-answers", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "book rating output", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The stored review scores are 5, 3, and 3. Their average is 11 / 3 = 3.666..., and the method rounds that to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_r", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 2, + "question_summary": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_r", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This snippet explicitly teaches how to trace the state of 'self' across multiple method calls using a nearly identical 'Book' class structure with an 'append' method and an average calculation." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Directly models the state-tracking logic (appending to a list in an object) required to solve the question." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Clarifies the behavior of the '.append()' method, which is crucial for understanding how the review scores are stored." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Provides a reference for the exact class structure, helping the student recognize the pattern of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Explains state tracking and the sum/len average pattern." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Validates how lists grow with append." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain the OOP mechanics (classes, self, append) very well. However, they do not explicitly define the 'round(value, 1)' function or the built-in 'sum()' and 'len()' functions, which are necessary for a student with zero Python knowledge to perform the final calculation accurately.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the OOP structure is covered, the mathematical built-ins used in the return statement are not explained.", + "missing_concepts": [ + "Built-in function: round(x, n) - rounding to n decimal places", + "Built-in function: sum() - totaling a list", + "Built-in function: len() - counting items in a list" + ], + "proposed_fix": "Add a snippet or AI example covering 'Common Built-in Math Functions for Collections' that explains sum, len, and round." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Common Math Built-ins for Lists. Content: Use `sum(list)` to add all numbers, `len(list)` to count items, and `round(number, 1)` to round to one decimal place. Example: `round(10/3, 1)` returns `3.3`.", + "why_helpful": "The question relies on a calculation involving all three of these functions. Without knowing what 'round(..., 1)' does, a student might guess 4 (b) or 3.67 (d).", + "why_maybe_unnecessary": "Students might infer sum/len from context, but 'round(..., 1)' is more specific.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:25:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q03", + "question_id": "sample-final-plus-answers-q03", + "exam_id": "sample-final-plus-answers", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "student grade formatting", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\nFor example, if\nstudents = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 75.\nBernard has received a grade of 80.\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']}. \")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {student['Grade']}. \")", + "c": "for student in students:\n print(f\"{student['Name']} has received a grade of \" + str(student[\"Grade\"]))", + "d": "for student, grade in students.items():\n print(f'{student} has received a grade of {grade}.')" + }, + "correct": "a", + "explanation": "Option A iterates through the list of dictionaries and prints each student's name together with that student's grade. The other options incorrectly call `.items()` on the list or use the wrong data access pattern.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 3, + "question_summary": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is a verbatim match for the exam question provided, containing the exact problem statement regarding list of dictionaries and grade formatting." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Identical problem statement including the specific requirements for grade formatting and dictionary keys." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "A duplicate of the question from a different exam source, reinforcing the likely pattern of the question." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a practical example of dictionary iteration logic and validating code segments, which helps a student understand why certain options are valid." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Directly answers the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the candidate list. A student can simply match the problem description to the snippet and find the corresponding correct code segment.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the question text is perfectly covered, the specific syntax for 'one decimal place' (f-string precision) is mentioned in the prompt but not explicitly demonstrated in the code snippets provided in the search text.", + "missing_concepts": [ + "f-string precision formatting (e.g., :.1f)", + "difference between list iteration and dictionary .items() iteration" + ], + "proposed_fix": "Add a dedicated 'cheat sheet' style snippet explaining list-of-dictionary iteration and f-string number formatting." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Printing List of Dictionaries with Formatting. Content: To iterate through a list of dicts: `for item in my_list: print(f\"{item['key']}\")`. To format decimals to 1 place: `{value:.1f}`.", + "why_helpful": "The exam question specifically mentions one decimal place, but Option A in the JSON actually omits the format specifier. Providing the specific syntax ensures the student can handle variations where precision is required.", + "why_maybe_unnecessary": "The 'source_exam' snippets likely already contain the full solution in the actual rendered card.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:26:13Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q04", + "question_id": "sample-final-plus-answers-q04", + "exam_id": "sample-final-plus-answers", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "phone number formatting", + "question": "You need to write a function called format_phone_number that formats phone numbers.\nThe output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) at various places.\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A calls `replace` but does not store its result, so it returns the original unchanged string. The other options all build and return the digits without the dashes.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# should all return \"0205251400\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 4, + "question_summary": "Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions", + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "This snippet contains the exact explanation for the question: it explicitly states that strings are immutable and that the `.replace()` method returns a new string without modifying the original, which is why Option A fails." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Directly explains the behavior of `.replace()` and string immutability, which is the key to identifying the incorrect code segment." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Provides the exact context and problem statement for this specific phone number formatting question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "The explanation within this snippet ('Strings in Python are immutable. The .replace() method returns a new string but does not modify the original') is sufficient to solve the problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include a direct explanation of the specific trap in the question (string immutability and return values of string methods).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps. The existing snippets cover both the question context and the underlying technical reason for the correct answer.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:26:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q05", + "question_id": "sample-final-plus-answers-q05", + "exam_id": "sample-final-plus-answers", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "pandas even-row selection", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.9\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that looks like this, when printed:\n\n B\n2 8.2\n4 3.6\n6 8.4\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters the even-numbered row labels and keeps column `B` as a one-column DataFrame, matching the printed target. The other options use invalid indexing, select the wrong column/positions, or return a Series instead of the shown DataFrame.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 5, + "question_summary": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet is a direct match for the question. It explicitly explains that using a boolean mask on the index (df.index % 2 == 0) and specifying the column as a list (['B']) is the correct way to filter even rows and return a one-column DataFrame." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides the specific logic for even-row indexing and DataFrame column selection needed for the answer." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Shows the exact DataFrame structure (rows 1-6) mentioned in the question, helping the student visually map the data to the code." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides general context for pandas DataFrame column operations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Contains the key explanation for the logic used in option A." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides the visual data context." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains the exact question text and an explanation that matches the target answer perfectly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are highly relevant, but the indexing logic (modulo operator on index) could be explained more generically for students to apply to other variations.", + "missing_concepts": [ + "The role of the modulo operator (%) in finding even/odd numbers", + "The distinction between .loc (label-based) and .iloc (position-based) selection" + ], + "proposed_fix": "Add a foundational snippet explaining how boolean masks work with df.index to select rows based on label properties." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "proposal": "Add the text of the DataFrame 'df' (rows 1-6) to this snippet so it is fully self-contained without needing to look at 'exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data'.", + "why_helpful": "It ensures the student has both the data context and the solution logic in a single view, which is critical for zero-knowledge students.", + "why_maybe_unnecessary": "The student can select multiple snippets, but a single consolidated card is more efficient for a cheat sheet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:26:52Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q06", + "question_id": "sample-final-plus-answers-q06", + "exam_id": "sample-final-plus-answers", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "pandas df2 derivation", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False).loc[:, [\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A would keep all five rows after sorting the index descending, so it would not produce the shown three-row df2. The other options can all produce rows 4, 3, and 2 with columns A, C, and D in the displayed order.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ], + "evidence_topics": [ + "String Operations and Methods" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 6, + "question_summary": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ], + "evidence_topics": [ + "String Operations and Methods" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This snippet is a verbatim match for the exam question, explicitly explaining that Option A is incorrect because it retains all 5 rows of df1 while df2 only has 3 rows." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Direct answer and rationale for the exact question asked." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides general logic for selecting specific rows and columns in a DataFrame, which helps understand options B, C, and D." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Shows a visually similar DataFrame structure (4 columns, multiple rows) and the pattern of derivation via selection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Provides the complete logic needed to solve the problem by identifying the mismatch in row counts." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-7-w4-string-fundamentals' contains the identical question and a clear explanation of the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gap exists because the exact question is present in the source exam bank.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:27:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q07", + "question_id": "sample-final-plus-answers-q07", + "exam_id": "sample-final-plus-answers", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "datetime month parser", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "`\"03/02/2013\"` is parsed with `%m/%d/%Y`, so its month is 3. `\"03.02.2013\"` matches neither separator rule and becomes `None`. `\"03-02-2013\"` is parsed with `%d-%m-%Y`, so its month is 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 7, + "question_summary": "Which of the following code lines could NOT have created df2 from df1?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 7, + "question_summary": "Which of the following code lines could NOT have created df2 from df1?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This snippet is a direct match for the exam question, containing the exact code, input values, and a step-by-step explanation of the return value logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Directly explains the month parsing logic for both date formats used in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Provides context for handling strings with '-' separators, which mirrors one of the branching conditions in the question." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Helps a novice understand basic 'for' loop iteration and 'if/else' membership checks ('in') used in the code." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Contains the exact solution and reasoning for the provided problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the verbatim question and explanation from a previous exam, making the answer explicitly available.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact match exists, the snippets lack a general-purpose reference for datetime formatting codes which would be necessary if the question parameters (like date formats) were slightly altered.", + "missing_concepts": [ + "General datetime format specifiers reference (%m, %d, %Y)", + "List comprehension syntax explanation" + ], + "proposed_fix": "Add a summary item detailing common strptime format characters to enable solving variations of this parsing logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Formatting Cheat Sheet' snippet listing %d (day), %m (month), %Y (year), and %H:%M (time).", + "why_helpful": "It empowers the student to decode any strptime format string rather than just recognizing this specific exam solution.", + "why_maybe_unnecessary": "The database already contains many specific exam questions covering these codes individually.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:27:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q08", + "question_id": "sample-final-plus-answers-q08", + "exam_id": "sample-final-plus-answers", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "dictionary comprehension lengths", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the only dictionary comprehension that maps each string to its own length. Option B makes a list, Option C makes a set, and Option D reverses the intended key-value direction.", + "code_context": "list_1 = [ ... ]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 8, + "question_summary": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 8, + "question_summary": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This snippet is a direct match for the question. It explicitly states the correct answer and explains the difference between dictionary, list, and set comprehensions, which is exactly what a student needs to distinguish between the provided options." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Directly identifies the identical question and explains the correct syntax (Option A) vs incorrect ones (Option B, C)." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Reinforces the pattern by presenting a nearly identical problem (mapping words to their lengths in a dictionary) and confirming the correct approach." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides another example of creating a dictionary from lists (names to ages), helping the student recognize the 'key: value' mapping pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Provides the exact solution and high-level explanation of the syntax differences." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippet 'exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions' is the exact same question and answer pair. It provides both the correct answer and a conceptual explanation of why other structures (lists, sets) are incorrect.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are exceptionally strong because they include the exact question being asked. No conceptual gaps exist for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:28:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q09", + "question_id": "sample-final-plus-answers-q09", + "exam_id": "sample-final-plus-answers", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Datetime parsing", + "question": "Take a look at the following code segment.\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "The first string contains `/`, so it is parsed as month/day/year and gives month 3. The second string contains neither `-` nor `/`, so it becomes `None`. The third contains `-`, so it is parsed as day-month-year and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 9, + "question_summary": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 9, + "question_summary": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime", + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This snippet is a direct match for the question provided. It explicitly explains the logic: strings with '/' use %m/%d/%Y (month 3), strings with '-' use %d-%m-%Y (month 2), and others return None." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Directly explains the specific datetime parsing logic and format codes used in the question." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Helps a student understand the 'for loop' and 'append' logic used to build the result list in the code context." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Illustrates how calling a function with different arguments leads to different return values, which is the core of tracing the get_months call." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Provides the exact logic and mapping needed to solve the specific problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains an identical question/explanation snippet that breaks down the exact strings and format codes used in the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While a direct answer exists, there is no general reference for datetime format codes (%d, %m, %Y) or the .month attribute, which would be necessary if the question were slightly modified.", + "missing_concepts": [ + "datetime.strptime format codes documentation", + "datetime object attributes (month, day, year)", + "list comprehension basics" + ], + "proposed_fix": "Add a summary card for the 'datetime' module covering common formatting directives and object properties." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Cheat Sheet' snippet: '%d: Day (01-31), %m: Month (01-12), %Y: Year (4-digit). datetime.strptime(str, format) parses strings; object.month extracts the month integer.'", + "why_helpful": "It would allow students to solve any datetime parsing question rather than relying on finding a verbatim copy of the exam question.", + "why_maybe_unnecessary": "The verbatim snippet already exists in this specific dataset.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:28:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q10", + "question_id": "sample-final-plus-answers-q10", + "exam_id": "sample-final-plus-answers", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "Datetime day-of-year", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives a `timedelta`; taking `.days` and adding 1 makes January 1 equal to day 1. The other options either misuse `timedelta`, add an integer directly to a `datetime` difference, or use an invalid date.", + "code_context": "day_of_year(datetime(2022, 2, 1))\n# should return 32" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 10, + "question_summary": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 10, + "question_summary": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime", + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This snippet is a near-identical exam question that explicitly explains the logic: subtracting two datetimes creates a timedelta, accessing .days gives the integer difference, and adding 1 converts 0-based indexing to the 1-366 range." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly addresses the exact problem with a clear explanation of the underlying mechanics (timedelta and .days attribute)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This single snippet provides the complete conceptual and syntactical solution required for the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippet list contains the exact same question (or a very close variant) along with an explanation that maps directly to option 'a'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent because the database already contains a sample exam question covering this specific datetime application.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:28:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q11", + "question_id": "sample-final-plus-answers-q11", + "exam_id": "sample-final-plus-answers", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary comprehension", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Only option A is a dictionary comprehension with each string as the key and its length as the value. The others create a list, a set, or a dictionary with the mapping reversed.", + "code_context": "list_1 = [...]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 11, + "question_summary": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 11, + "question_summary": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This snippet contains the exact same question and options, explicitly identifies 'A' as the correct answer, and defines it as a 'standard dictionary comprehension' while explaining why the other options (list, set) are incorrect." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Directly answers the specific exam question with a clear breakdown of why option A is correct and why B and C are wrong." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Presents an almost identical scenario (list of words to dictionary of lengths) which reinforces the pattern recognition for dictionary comprehension syntax {key: value for ...}." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides additional context on creating dictionaries from existing list data, which helps understand the general relationship between names/keys and ages/values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This single snippet provides the verbatim question, the answer, and the terminology needed to distinguish the correct syntax from the distractors." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question and a detailed explanation of the correct choice. A student with zero knowledge can simply match the 'standard dictionary comprehension' description to the syntax in option A.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the specific question is answered, the general 'rule' of comprehension syntax (brackets vs. braces and the colon) is only implied by the specific examples.", + "missing_concepts": [ + "Explicit syntax rule: {k: v for ...} = Dict, [v for ...] = List, {v for ...} = Set" + ], + "proposed_fix": "Add a summary item that lists the different types of comprehensions and their corresponding bracket/brace syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Comprehension Syntax' summary card: 1. Dictionary: {key: value for item in iterable}, 2. List: [value for item in iterable], 3. Set: {value for item in iterable}.", + "why_helpful": "It allows the student to answer any variation of this question (e.g., 'create a set' or 'create a list') rather than just memorizing this specific instance.", + "why_maybe_unnecessary": "The existing snippets already label the types, which might be enough for a single-question exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:29:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q12", + "question_id": "sample-final-plus-answers-q12", + "exam_id": "sample-final-plus-answers", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Case swapping", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[x if x in 'abcdefghijklmnopqrstuvwxyz'.upper() else x.lower() for x in list_1]", + "c": "Both achieve what you want", + "d": "None achieves what you want" + }, + "correct": "a", + "explanation": "Option A explicitly checks whether each character is lowercase and flips the case accordingly. Option B leaves uppercase letters unchanged instead of converting them to lowercase.", + "code_context": "list_1 = [...]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 12, + "question_summary": "You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-12-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 12, + "question_summary": "You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-12-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-12-w2-conditions", + "exam-intro_python_sample_final_24_25-12-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Directly identifies the 'case swapping' problem and confirms that conditional logic within a list comprehension is the standard approach for this task." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Matches the exact problem statement (flipping upper and lower case letters in a list) and mentions conditional logic." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides context for working with string alphabets and converting strings to lists, relevant for understanding the logic in Option B." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Shows how functions/methods can be applied to string data, reinforcing the concept of string method usage." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Primary topical match." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Helps clarify alphabet string membership used in Option B." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the best snippet identifies the problem, its rationale ('Both options implement...') actually contradicts the specific logic in this question's Option B (which fails to swap cases). Without knowing '.islower()', a student might be misled by the snippet into choosing the 'Both' option.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets provide the context of 'case flipping' but lack definitions for the boolean method '.islower()' and the ternary list comprehension syntax.", + "missing_concepts": [ + ".islower() string method", + "ternary conditional syntax within list comprehensions", + "Difference between membership testing (in) and boolean checks (islower)" + ], + "proposed_fix": "Add a foundational snippet explaining string inspection methods (.islower, .isupper) and the [x if cond else y for x in list] syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet defining string case methods (.upper(), .lower(), .islower()) and the syntax for 'if-else' logic inside a list comprehension.", + "why_helpful": "Essential for a zero-knowledge student to evaluate why 'islower()' is the correct check vs the 'in alphabet' check used in Option B.", + "why_maybe_unnecessary": "Snippet 12 provides a shortcut, but it's risky due to conflicting rationales between exams.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:29:44Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q13", + "question_id": "sample-final-plus-answers-q13", + "exam_id": "sample-final-plus-answers", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Comparisons and types", + "question": "Suppose you have three variables x, y, z, as follows:\nx = '3'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string `'3'` is not equal to the integer `3`, while `3 == 3.0` is `True`. The chained comparison `x == y == z` means `(x == y) and (y == z)`, so it is `False`.", + "code_context": "x = '3'\ny = 3\nz = 3.0" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 13, + "question_summary": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 13, + "question_summary": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet is a perfect match for the question. It explicitly states that '3' == 3 is False, 3 == 3.0 is True, and explains exactly how the chained comparison x == y == z is evaluated as (x == y) and (y == z)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Directly provides the answer and full logic for the identical question." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Provides the fundamental definitions of Python types (str, int, float, etc.), which helps a student understand why a string '3' differs from the number 3." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Uses the same variable set (x='3', y=3, z=3.0) in a different comparison context, reinforcing how these types interact." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Independently sufficient as it contains the exact logic and explanation for every part of the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains a snippet that is an exact replica of the question with a comprehensive explanation of the comparison rules (type inequality for strings vs numbers, value equality for ints vs floats, and the mechanics of chained comparisons).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps found. The existing snippets cover both the specific instance and the underlying concepts of types and comparisons.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q14", + "question_id": "sample-final-plus-answers-q14", + "exam_id": "sample-final-plus-answers", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Loops", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. (In the first iteration, just take the previous number to be 0.)\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e.: only the sums).", + "options": { + "a": "i = 0\nwhile i <= 10:\n print(i + (i-1))\n i += 1", + "b": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "b", + "explanation": "Option B correctly tracks the previous number and starts the loop at 1, producing the required sums. Option A starts at 0 and prints `-1` on the first iteration, so it does not match the specification.", + "code_context": "# target outputs: 1, 3, 5, ..., 19" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 14, + "question_summary": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops" + ], + "evidence_topics": [ + "Loops" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 14, + "question_summary": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops" + ], + "evidence_topics": [ + "Loops" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops", + "exam-intro_python_sample_final_24_25-14-w2-loops" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "This snippet is a direct match for the question logic, explicitly stating that the program should iterate from 1 to 10, sum current/previous, and that Option B is correct because it updates the 'previous' state correctly." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "Directly explains the logic for this specific sum-of-previous-and-current pattern." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Provides a crucial boundary hint by noting that a loop running while 'i < 11' iterates 'from 1 to 10', helping the student understand the 'range(1, 11)' in the options." + }, + { + "item_id": "ks-bddafc66a0", + "rationale": "Shows the basic for-loop syntax (for variable in sequence), which is fundamental to identifying the structure used in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "By itself, this snippet essentially provides the answer and the reasoning for the specific logic required." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Clarifies that to get integers up to 10, the range/condition must go up to 11." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-14-w2-loops' describes the exact scenario and logic. Combined with the boundary explanation in 'exam-Test Resit...-4-w2-loops', a student can confidently select Option B.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent because the dataset contains a variant of the exact same question. The only slight difficulty might be understanding the exact behavior of 'range(1, 11)', but one snippet provides a high-level hint for this.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:23Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q15", + "question_id": "sample-final-plus-answers-q15", + "exam_id": "sample-final-plus-answers", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Functions and scope", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "Result is a local name and cannot be referenced outside of the function.", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "`result` is defined inside `cube`, so it exists only within the function scope. The line `print(result)` is outside the function, where that local name is not defined.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 15, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-15-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 15, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-15-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-15-w2-conditions", + "exam-intro_python_sample_final_24_25-15-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "This snippet describes the exact scenario from the question (a 'cube' function with a 'result' variable) and explains that it is local and inaccessible from the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Provides a direct, identical example of the error and the correct explanation." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the formal definition of local and global scope, explaining that local names are 'only known inside the function'." + }, + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "Reinforces the concept with a similar example ('power' function) and explicitly mentions that 'print(result)' fails because it is called in the global scope." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Directly answers the specific question scenario." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the underlying rule that allows a student to generalize why the error occurs." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets include a near-identical exam question and the precise lecture definition required to understand why a local variable is inaccessible outside its function.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets perfectly cover the 'Scope' concept as it relates to this question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:39Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q16", + "question_id": "sample-final-plus-answers-q16", + "exam_id": "sample-final-plus-answers", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "Lambda functions", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "The first lambda returns `1 + 2 = 3`, the second returns `1 * 2 = 2`, and `3 ** 2` equals `9`.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 16, + "question_summary": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns" + ], + "evidence_topics": [ + "Higher-Order Patterns" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 16, + "question_summary": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns" + ], + "evidence_topics": [ + "Higher-Order Patterns" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "This snippet is an exact match for the question and provides a clear, step-by-step mathematical breakdown of the lambda calls and the final exponentiation result." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "Directly answers the question with the exact same code and values." + }, + { + "item_id": "ks-58858d6d96", + "rationale": "Explains the fundamental syntax of lambda functions (lambda params: expression), which is essential for a student with zero knowledge to understand how the code works." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Reinforces the concept of functions as objects and demonstrates the exponentiation operator (**), which is the final step of the calculation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "Provides the specific solution and mathematical logic." + }, + { + "item_id": "ks-58858d6d96", + "rationale": "Provides the general rule for lambda functions so the student can parse the code structure." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The collection includes the identical exam question and answer key, along with a lecture snippet explaining the underlying syntax.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover both the specific instance and the general syntax. No significant conceptual gaps exist for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:58Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q17", + "question_id": "sample-final-plus-answers-q17", + "exam_id": "sample-final-plus-answers", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "Empty-sequence equality chain", + "question": "You have the following function called main:\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat will be printed by the following lines:\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))", + "options": { + "a": "True\nFalse\nFalse", + "b": "False\nFalse\nTrue", + "c": "True\nFalse\nTrue", + "d": "True\nTrue\nTrue" + }, + "correct": "d", + "explanation": "The first call builds [True, True, True], the second call builds [False, False, False], and the third call also builds [False, False, False]. In all three cases the chained equality compares three identical booleans, so each printed result is True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 17, + "question_summary": "What will be printed by the function calls in the main function provided?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 17, + "question_summary": "What will be printed by the function calls in the main function provided?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "rationale": "This snippet appears to be from the exact same question or a near-identical variant, explicitly explaining that the function checks if elements are consistently empty or non-empty." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "rationale": "Directly explains the logic of the problem: checking for empty vs non-empty consistency across multiple calls." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Demonstrates the 'for loop with an if-condition appending to a list' pattern used in the code context." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Provides an example of complex boolean evaluation and comparison logic similar to the chained equality return." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "rationale": "Provides the high-level logic and correct interpretation of the empty sequence checks." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Helps trace the list-building process (y.append)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first recommended snippet describes the exact logic of this specific exam question, noting that empty sets/lists and non-empty sequences are processed consistently within each function call.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is explained, a student with zero Python knowledge might still struggle with the specific behavior of chained equality (y[0] == y[1] == y[2]) and the fact that an empty dictionary {} has a length of 0.", + "missing_concepts": [ + "chained equality behavior (a == b == c)", + "len() results for empty containers like {} and []" + ], + "proposed_fix": "Add a foundational snippet explaining common sequence lengths and the chained comparison operator." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Sequence Properties' card showing that len([]) == 0, len({}) == 0, and len('') == 0, and explaining that a == b == c is only True if all three are identical.", + "why_helpful": "It bridges the gap for absolute beginners who might not know {} is a dictionary or that comparisons can be chained in Python.", + "why_maybe_unnecessary": "The existing 'intro_python_sample_final' snippet already hints at this logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:31:16Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q18", + "question_id": "sample-final-plus-answers-q18", + "exam_id": "sample-final-plus-answers", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "List chunking into sublists", + "question": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nFor example:\nIf you have the original list x as:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nHow do you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:(i + 3)] for i in range(0, 7, 3)]", + "b": "y = [x[i[0]::3] for i in enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "a", + "explanation": "Option A slices the list in chunks of length 3 starting at indices 0, 3, and 6, which produces the three required sublists in order.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 18, + "question_summary": "How do you break a list into a list of lists, where each sublist contains 3 elements?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-18-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 18, + "question_summary": "How do you break a list into a list of lists, where each sublist contains 3 elements?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-18-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-18-w2-conditions", + "exam-intro_python_sample_final_24_25-18-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "This snippet is a direct match for the question, providing the exact code for Option A and explaining how the range function and slicing work together to partition the list." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Directly answers the exam question and explains the logic of the correct option." + }, + { + "item_id": "aiq-3", + "rationale": "Provides a clear manual breakdown of how range(start, stop, step) generates values, which is essential for understanding the indices 0, 3, and 6." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Introduces the concept of list slicing (start:stop:step), which helps a student understand the x[i:i+3] syntax used in the answer." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Contains the specific problem, the correct answer, and the underlying logic." + }, + { + "item_id": "aiq-3", + "rationale": "Explains the range function logic used to generate the chunk starting points." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One candidate snippet contains the exact same question and explains the correct answer. Combined with a breakdown of the range function, a student with no prior knowledge can verify why 'a' is correct.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the solution and the range logic, but do not explicitly explain the 'List Comprehension' syntax (the [x for x in list] structure).", + "missing_concepts": [ + "List comprehension syntax" + ], + "proposed_fix": "Add a small snippet or AI example explaining that [expression for item in iterable] is a way to build a list by repeating an action." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "List Comprehension: [expression for item in iterable] creates a new list by running the expression for every item. Example: [i*2 for i in range(3)] generates [0, 2, 4].", + "why_helpful": "It helps students understand that the brackets in the answer aren't just for a list, but are a loop that generates sublists.", + "why_maybe_unnecessary": "The student might infer the behavior from the direct-match snippet provided in the exam-intro snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:31:33Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q19", + "question_id": "sample-final-plus-answers-q19", + "exam_id": "sample-final-plus-answers", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary running totals", + "question": "You have to write a function called main that accepts a dictionary as an input argument.\nBoth the keys and the values of the input are integers.\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary whose keys are smaller than or equal to the output key in question.\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "b": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "c": "Both of the above work as intended", + "d": "None of the above works as intended" + }, + "correct": "c", + "explanation": "The first program computes each output value by summing all input values whose keys are less than or equal to the current key. The second program accumulates values in ascending key order, which yields the same running totals for each key.", + "code_context": "main({5: 1, 2: 5, 4: 2})\n# expected result:\n# {5: 8, 2: 5, 4: 7}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 19, + "question_summary": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 19, + "question_summary": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "This snippet is a direct match for the question logic. It explicitly mentions calculating cumulative sums where keys are <= the output key and confirms that both methods (Option C) are correct, even noting that one is more efficient." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "Directly identifies the 'running totals' logic and confirms that both common implementations (list comprehension vs. sorted loop) work." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the basic pattern of iterating over a collection to populate a dictionary, which helps understand the 'result[key] = ...' structure." + }, + { + "item_id": "aiq-5", + "rationale": "Shows the usage of the sum() function and returning a dictionary, which are core components of the code in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "Provides the conceptual answer and confirms the validity of the two approaches described in the question options." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet in the candidate list is effectively a summary of this exact exam question. It describes the goal (cumulative sums based on keys <= current key) and identifies the correct answer as 'Both methods' (C).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the best snippet gives the answer directly, the supporting snippets do not explicitly explain 'list comprehensions' or the 'sorted()' function for a student with zero knowledge who wants to verify the code themselves.", + "missing_concepts": [ + "List comprehensions (for Option A)", + "Dictionary iteration using .items()", + "The effect of sorted() on dictionary keys" + ], + "proposed_fix": "Add a snippet that demonstrates a list comprehension inside a loop or a comparison of dictionary iteration methods." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining 'Sorted Dictionary Iteration': 'To process a dictionary in order of its keys, use `for key in sorted(my_dict.keys()):`. This ensures you visit keys from smallest to largest, which is useful for calculating running totals.'", + "why_helpful": "It directly explains the logic behind Option B, which is often the more confusing part of this specific question for beginners.", + "why_maybe_unnecessary": "The 'best' snippet already tells the student that both options work, which might be enough for a 'cheat sheet' context.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:31:54Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q20", + "question_id": "sample-final-plus-answers-q20", + "exam_id": "sample-final-plus-answers", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary equality with zip and enumerate", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) produces key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same key-value pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 20, + "question_summary": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 20, + "question_summary": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "This snippet is a direct match for the question logic, explicitly stating that d1 (from zip) and d2 (from enumerate) result in the same dictionary." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Provides the direct answer and the final dictionary state for both constructions." + }, + { + "item_id": "ks-65c4de2e9d", + "rationale": "Explains dictionary equality (unordered) and the basic structure of key:value pairs." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows a concrete example of a dictionary structure {1: 10, ...} which helps a novice visualize what d1 and d2 look like." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Directly identifies that zip and enumerate produce the same dictionary in this context." + }, + { + "item_id": "ks-65c4de2e9d", + "rationale": "Confirms that comparing two dictionaries with '==' checks if they contain the same key-value pairs regardless of order." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question and its solution are present in the exam-intro_python_sample_final snippet.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is directly provided by one snippet, there is a lack of fundamental explanation for how 'zip' and 'enumerate' work independently.", + "missing_concepts": [ + "Explicit definition of zip(list1, list2) pairing behavior", + "Explicit definition of enumerate(list, start) index-value pairing" + ], + "proposed_fix": "Add a lecture-based snippet (ks) that defines zip and enumerate mechanics for general list processing." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'zip(l1, l2) creates pairs of elements from two lists at the same index. enumerate(l, start) creates pairs of (index, element), where the index starts at the specified value (default 0).'", + "why_helpful": "It allows a student to derive the answer logically if the lists or indices were modified, rather than relying on a memorized exam answer.", + "why_maybe_unnecessary": "The direct exam match already provides the answer for this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:32:14Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q21", + "question_id": "sample-final-plus-answers-q21", + "exam_id": "sample-final-plus-answers", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary iteration semantics", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not (key, value) pairs, so `for key, value in d1:` is invalid. The other three variants all sum the dictionary values correctly.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 21, + "question_summary": "The following codes all print the same value, except one. Which one?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 21, + "question_summary": "The following codes all print the same value, except one. Which one?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "This is an exact match for the question, providing both the problem statement and the explicit explanation that iterating directly over a dictionary yields keys, leading to a ValueError if unpacking into two variables." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Directly answers the specific question and explains the error in option A." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Provides the general rule for dictionary iteration: .keys() for keys, .values() for values, and .items() for (key, value) pairs, which covers the underlying logic for all options." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the use of .values() and .keys() in a practical code snippet, reinforcing the syntax used in options B, C, and D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Contains the exact question and the 'why' behind the correct answer." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Supplies the conceptual framework for understanding how to correctly iterate over keys, values, or pairs." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the exact exam question from a previous year along with a lecture snippet that explains the relevant semantics of dictionary looping.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps found; the provided snippets cover both the specific instance and the general principle.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:32:29Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q22", + "question_id": "sample-final-plus-answers-q22", + "exam_id": "sample-final-plus-answers", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "String count method", + "question": "You have the following string\nx = 'Amsterdam'\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method `count` must be called on the string object itself. `x.count('a')` returns 1 for the lowercase 'a' in 'Amsterdam'.", + "code_context": "x = 'Amsterdam'" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 22, + "question_summary": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 22, + "question_summary": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions", + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "This snippet contains the exact question and explains that .count() is a string method requiring dot notation on a string object, directly answering why option B is correct." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Directly addresses the question and provides the specific syntax rule for the count method." + }, + { + "item_id": "ks-ab66f3bab6", + "rationale": "Explains the fundamental difference between methods (attached to objects) and functions, which is the core concept being tested." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Sufficient on its own as it provides both the answer and the explanation for this specific problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet is a near-perfect match for the exam question and provides the necessary syntax explanation for a novice to identify the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets perfectly cover the syntax of calling a method. However, they don't explicitly mention string case-sensitivity (why Amsterdam has only one 'a'), which is part of the question's logic.", + "missing_concepts": [ + "String case-sensitivity in Python", + "Standard string method definitions (count, find, replace)" + ], + "proposed_fix": "Add a lecture snippet or knowledge card specifically covering common string methods and their case-sensitive nature." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet detailing that Python string methods like .count(), .find(), and .index() are case-sensitive by default (e.g., 'A' != 'a').", + "why_helpful": "It ensures the student understands why the answer is 1 and not 2, reinforcing the logic behind the specific example provided in the question.", + "why_maybe_unnecessary": "The syntax rule (dot notation vs function call) is the primary hurdle for the question, which is already covered.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:32:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q23", + "question_id": "sample-final-plus-answers-q23", + "exam_id": "sample-final-plus-answers", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "Higher-order function returning 30", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "The first call returns (1+5)+(2+5)+(3+5)+(4+5)=30, and the second returns 1^2+2^2+3^2+4^2=30. Both produce the requested result.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 23, + "question_summary": "Which of the following function calls would return the number 30 as a result?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 23, + "question_summary": "Which of the following function calls would return the number 30 as a result?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments", + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "This snippet is a direct match for the question and explicitly provides the arithmetic breakdown (6+7+8+9=30 and 1+4+9+16=30) for both function calls." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Provides the direct answer and calculation logic for the exact question." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Helps a student understand the concept of passing functions (like square/cube) as arguments to another process." + }, + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "rationale": "Explains the *args syntax, which is necessary to understand how multiple numbers (1, 2, 3, 4) are being handled by the calculation function." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Contains the full logic and verification for both options presented in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet contains the exact question and its solution. Even without knowing Python, a student can match the numbers and the sum result (30) from the snippet text.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The direct answer is present, but the underlying concept of 'lambda' is only implicitly explained via the arithmetic results.", + "missing_concepts": [ + "Explicit lambda syntax definition (lambda parameters: expression)" + ], + "proposed_fix": "Add a dedicated snippet or AI common question that briefly defines lambda as a 'mini-function on one line' to bridge the gap between seeing the code and performing the math." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Lambda Basics' that explains: 'lambda x: x + 5' means 'take x and add 5 to it'.", + "why_helpful": "It allows the student to perform the calculation themselves rather than just relying on matching the search text of a previous exam question.", + "why_maybe_unnecessary": "The existing sample final snippet already performs the calculation for the student.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:33:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q24", + "question_id": "sample-final-plus-answers-q24", + "exam_id": "sample-final-plus-answers", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "Circle area imports and aliases", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C aliases the module as `constants`, so `math.pi` is not defined there. The other three options reference pi correctly.", + "code_context": "# area formula\n# pi * r ** 2" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 24, + "question_summary": "Which script does NOT print the correct answer for the area of a circle?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-24-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 24, + "question_summary": "Which script does NOT print the correct answer for the area of a circle?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-24-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-24-w2-conditions", + "exam-intro_python_sample_final_24_25-24-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This snippet is a direct match for the question, providing the exact answer (C) and explaining that aliasing a module with 'as' makes the original module name unavailable in the namespace." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "Directly answers the question and explains the mechanics of module aliasing." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Demonstrates the use of the exponentiation operator (**), which is used in the area formula (r ** 2)." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains the basic print function, which is used to output the result in all options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This single snippet contains the identical question, the correct answer, and a full explanation of the logic." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains the exact question and explanation from a sample final exam, making the answer trivial to find.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps exist because the exact question is present in the source materials.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:33:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q01", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q01", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "6-OOP-1", + "question": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor, then the \"mode\" attribute should be equal to \"land\".\n\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A defines an initializer with a required vehicle name and a default mode of \"land\", then stores both on the instance using self.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction. The \"name\" attri", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-init-default", + "rationale": "This snippet explicitly addresses the core concept of the question: using default values in the `__init__` constructor (e.g., `vehicle_mode='land'`) to make arguments optional." + }, + "top_three_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Directly explains the syntax for optional constructor arguments and default values required for the 'mode' attribute." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Contains the exact problem statement, allowing a student to recognize the question and apply the relevant concept." + }, + { + "item_id": "aiq-4", + "rationale": "Reinforces the concept of required vs flexible arguments, which helps in understanding how 'name' and 'mode' interact in the constructor." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Explains the default value mechanic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the specific context/requirements." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The 'manual-init-default' snippet provides the exact code pattern (class definition, __init__ method, and default parameter value) needed to identify Option A as correct.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover the 'default value' mechanic well, but don't explicitly explain why Option D (missing 'self') or Option C (using 'return') are incorrect for constructors.", + "missing_concepts": [ + "The role of 'self' as the first parameter in instance methods", + "The fact that __init__ should not return values" + ], + "proposed_fix": "Add a snippet explaining basic class structure and the necessity of 'self' for attribute assignment." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: OOP Fundamentals. Content: In Python, `__init__` is used to set attributes on a new object. Use `self.attribute_name = value`. Always include `self` as the first parameter. Example: `class MyClass: def __init__(self, val): self.val = val`", + "why_helpful": "This helps the student eliminate Option D (missing self) and Option C (incorrectly using return instead of self assignment).", + "why_maybe_unnecessary": "Option A is the only one showing both the correct default value syntax AND self-assignment, so the existing snippets might be enough to guess correctly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:33:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q02", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q02", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "6-OOP-2", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The reviews are 5, 3, and 3, so the average is 11 / 3 = 3.666..., which show_rating rounds to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Take a look at the following class definition. Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Ric", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This snippet provides a near-perfect structural and logical mirror of the question. It explicitly demonstrates how to 'Trace self state across multiple method calls' using a list of scores and calculating an average with sum() and len()." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Explains the core logic of maintaining state in a list and calculating a numerical average within a class method." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Directly matches the exam question, allowing the student to see the exact scenario and options they are likely to encounter." + }, + { + "item_id": "kp-manual-init-defaults-d2", + "rationale": "Clarifies the specific 'review_scores=None' to '[]' initialization pattern used in the question's constructor, which is a common source of confusion for beginners." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Covers the internal logic of the method calls and averaging." + }, + { + "item_id": "kp-manual-init-defaults-d2", + "rationale": "Covers the initialization logic for the mutable list attribute." + }, + { + "item_id": "ks-06b21ad349", + "rationale": "Provides the foundational context that a class is a 'blueprint' and __init__ is the constructor." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Between the exact question match and the AI-generated logic mirror, a student can easily connect the pattern of adding items to a list and then calculating an average. The only minor leap is the round() function.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage for OOP state management and list manipulation is excellent. The only missing element is an explicit definition of the built-in round() function's behavior with the second argument.", + "missing_concepts": [ + "The round(number, ndigits) built-in function" + ], + "proposed_fix": "Add a snippet explaining common math built-ins like round(), especially highlighting how the second argument controls decimal precision." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point: 'The round(value, n) function rounds a number to n decimal places. Example: round(3.6666, 1) results in 3.7.'", + "why_helpful": "The question requires choosing between 3.7 and 3.67; knowing how the '1' in round(..., 1) works is the final step to the correct answer.", + "why_maybe_unnecessary": "The term 'round' is intuitive enough for many students to guess the behavior correctly given the options.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:34:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q03", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q03", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "6-strings-1", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\n\nFor example, if:\nstudents = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 7.5.\nBernard has received a grade of 8.0.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']:.1f}.\")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {grade:.1f}.\")", + "c": "for student in students:\n print(f\"{student[\\\"Name\\\"]} has received a grade of {student[\\\"Grade\\\"]:.1f}.\")", + "d": "for student, grade in students:\n print(f\"{student} has received a grade of {grade:.1f}.\")" + }, + "correct": "a", + "explanation": "Option A iterates through each dictionary in the list and formats the student's name and grade correctly to one decimal place. The other options use the wrong iteration pattern or invalid access pattern for this data structure.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary in the students list has two keys: \"Name\" and \"Grade\". The correspondi", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is a near-exact match of the current question, including the specific requirement for displaying grades to one decimal place, allowing a student to identify the pattern immediately." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Matches the question prompt and constraints (list of dictionaries, f-string rounding) perfectly." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Another exact match of the problem scenario (students list with Name/Grade dictionaries)." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides context on iterating through lists to create or access dictionaries, which helps clarify why list iteration (Option A) is correct over dict.items() (Option B)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Matches the exact question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Matches the exact question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact question from previous exam iterations. A student can match the 'students' list and 'one decimal place' requirement directly to the resources.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact question exists in the bank, there is a lack of a generalized 'F-String Formatting Cheat Sheet' that explains the syntax for rounding floats (e.g., .1f), which would help a student understand *why* the answer is correct rather than just pattern matching.", + "missing_concepts": [ + "f-string float precision syntax (:.nf)", + "difference between list iteration and dictionary .items() iteration" + ], + "proposed_fix": "Add a dedicated key point or subtopic detail specifically for 'String Formatting with F-Strings' that explicitly demonstrates float rounding." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: F-String Float Formatting. Syntax: f'{value:.1f}' rounds to 1 decimal place. Example: price = 5.0; print(f'{price:.2f}') outputs 5.00.", + "why_helpful": "This provides the underlying logic for rounding, which is a core part of the question's 'distractor' logic (ensuring the student knows how to get 7.5 instead of 7.500000).", + "why_maybe_unnecessary": "Since the exact question is already in the database, the student might just copy the answer without needing the rule.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:34:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q04", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q04", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "6-strings-2", + "question": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character, at various places).\n\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A does not work because strings are immutable and number.replace(\"-\", \"\") returns a new string that is ignored. The function then returns the original unmodified number.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# all should return \"0205251400\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argum", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "This snippet explicitly states that 'Strings in Python are immutable' and that '.replace() returns a new string but does not modify the original,' which directly explains why Option A is the code segment that fails." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Provides the direct conceptual and specific explanation for the failure of the replace method in Option A." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Contains the full problem description for the 'format_phone_number' task, providing necessary context." + }, + { + "item_id": "aiq-2", + "rationale": "Introduces the important concept of whether a method 'mutates the list in place,' helping the student distinguish between in-place mutation and returning a new object." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Contains the exact logic needed to identify Option A as the incorrect implementation." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-4-w2-conditions' contains the verbatim explanation and rationale for the correct answer, specifically addressing string immutability and the behavior of the .replace() method.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets provide both the problem context and the specific technical explanation required to answer the question correctly.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:34:56Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q05", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q05", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-new_column-1", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] + df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x + df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\" + \"B\"]", + "d": "df[\"C\"] = df[\"A\" + \"B\"]" + }, + "correct": "a", + "explanation": "Option A performs elementwise addition between columns A and B and stores the result in column C. The other options either misuse map, index into the columns object incorrectly, or look for a non-existent combined column name.", + "code_context": "df has numeric columns \"A\" and \"B\"; column \"C\" should contain their sum." + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers. You'd like to create a column called \"C\", which contains the sum of", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "This snippet contains the exact question and specifically mentions 'Vectorized addition in Pandas', which explains the logic required to identify option A as the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Directly matches the question and provides the concept of vectorized addition." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "An exact replica of the question text from a different exam source." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Demonstrates the syntax for mathematical operations between Pandas structures to create a new Series/column." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides both the solution and the technical rationale for why the operation works." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact exam question and its correct answer, making it trivial for a student to answer correctly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the specific answer to this question but lack a general conceptual rule about the syntax of Pandas column assignment.", + "missing_concepts": [ + "General syntax for DataFrame column creation (df['new'] = expression)", + "Explicit definition of element-wise (vectorized) operations versus scalar operations" + ], + "proposed_fix": "Add a foundational 'Pandas Key Point' snippet that generalizes the pattern: 'To create a new column based on others, use the syntax: df[\"New\"] = df[\"Col1\"] + df[\"Col2\"]'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a conceptual snippet explaining 'Pandas Column Arithmetic' that shows how df['C'] = df['A'] + df['B'] performs a row-by-row sum and stores it in 'C'.", + "why_helpful": "It helps the student understand the 'why' and apply the knowledge to variations (e.g., subtraction or multiplication) rather than just memorizing one specific question.", + "why_maybe_unnecessary": "The student can already answer this exact question because it is duplicated in the exam snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:35:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q06", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q06", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-selection-1", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that only contains those elements of column \"B\" in df that have an even-numbered index. Which of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters rows whose index is even and selects column B while keeping the result as a DataFrame by using [[\"B\"]]. Option D would return a Series, not a DataFrame, and the other options do not select the requested data correctly.", + "code_context": "df printed as:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You have a pandas DataFrame called df that looks like this, when printed: A B C D 1 9.1 9.5 9.0 6.0 2 6.4 8.2 7.5 1.7 3 2.5 5.3 8.8 3.0 4 6.7 3.6 7.2 6.9 5 8.4 1.9 8.2 3.3 6 8.1 8.", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ], + "evidence_topics": [ + "Inspecting and Selecting Data" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet provides the exact reasoning required: it explains that Option A is correct because it uses a boolean mask on the index for even numbers and specifies ['B'] as a list to ensure the result is a DataFrame." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Contains the explicit logic for the correct answer, including the mask and the list-selection for DataFrame output." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Matches the exact question text and data table provided in the prompt, providing perfect context." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Explains the [start:stop:step] slicing syntax (1::2), which helps a student understand why Option D (2::2) might be tempting but potentially incorrect compared to the boolean mask." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides the 'why' for the correct answer." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides the 'what' (the specific problem setup)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets contain an identical question and a clear explanation of the specific syntax nuances (boolean mask vs slicing, and Series vs DataFrame return types).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are highly effective. The only minor issue is a metadata mismatch where a key Pandas snippet is tagged with 'string-operations'.", + "missing_concepts": [ + "Explicit difference between .loc slicing (which returns a Series if a single string is passed) and list-passing (which returns a DataFrame)." + ], + "proposed_fix": "Ensure snippets explaining .loc explicitly contrast df.loc[rows, 'col'] vs df.loc[rows, ['col']]." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "proposal": "Update the 'topic' from 'string-operations-and-methods' to 'Inspecting and Selecting Data' or 'Pandas Indexing'.", + "why_helpful": "The current tag is misleading as the content is about Pandas DataFrame selection, not string manipulation.", + "why_maybe_unnecessary": "The search_text is already accurate and will be found by the RAG system regardless of the label.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:35:43Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q07", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q07", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-sorting-1", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\n\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False)[[\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A sorts the entire DataFrame by index in descending order and would include rows 5 and 1 as well, so it would not match df2. The other options all produce rows 4, 3, and 2 with columns A, C, and D.", + "code_context": "print(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This snippet contains the exact logic and explanation for why Option A is the correct answer to this specific question, explicitly stating that sort_index would result in a 5-row DataFrame instead of the required 3 rows." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Provides the direct answer and logic for the specific question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Shows a similar Pandas DataFrame structure and selection context." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces the context of Pandas DataFrame column operations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This snippet alone provides the solution and the reasoning required to identify the correct choice." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One of the candidate snippets is an exact match for the question and explanation, making the answer clear even to a student with no prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the direct answer but lack general definitions for the specific Pandas methods used in the alternative (incorrect) options.", + "missing_concepts": [ + "Explicit difference between .loc (label-based, inclusive) and .iloc (position-based, exclusive)", + "Behavior of .sort_values vs .sort_index in Pandas" + ], + "proposed_fix": "Add a snippet explaining the syntax and slicing rules for .loc and .iloc to help students verify options B, C, and D." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a foundational snippet explaining that .loc[2:4] includes labels 2, 3, and 4, whereas .iloc[[3, 2, 1]] selects the 4th, 3rd, and 2nd rows respectively.", + "why_helpful": "This allows the student to understand why the other options (B, C, D) *could* have created df2, rather than just knowing why A could not.", + "why_maybe_unnecessary": "The direct explanation for Option A in the existing snippet is already sufficient to select the right answer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:36:15Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q08", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q08", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-string-1", + "question": "There is a pandas Series called s, which contains Dutch municipality and corresponding province names, separated by a semicolon and a whitespace. The following, for example, is an element of this Series: \"Amsterdam; Noord-Holland\".\n\nYou'd like to create a new Series that only contains the municipality names from s in the same order. Which of the following code lines will achieve what you want?", + "options": { + "a": "s.map(lambda x: x.split(\"; \")[0])", + "b": "s.split(\"; \")[0]", + "c": "s.lambda(x.split(\"; \"))", + "d": "s.str[:9]" + }, + "correct": "a", + "explanation": "Option A applies split('; ') to each element in the Series and takes the first part, which is the municipality name. The other options either do not operate elementwise or do not reliably extract the municipality name.", + "code_context": "Example element in s:\n\"Amsterdam; Noord-Holland\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet describes the exact scenario of a Series 's' with municipality and province names separated by '; ' and explicitly identifies the '.map()' method as the solution for applying a function like split." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly matches the question scenario and explains the use of the .map() method for elementwise transformation." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides a conceptual example of creating a new Series from an existing one based on a calculation (square of difference), reinforcing the 's.operation' pattern." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions splitting strings based on separators (dashes in this case), which helps a student understand what the 'split' part of the correct option does." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet is independently sufficient as it contains the exact problem statement and identifies '.map()' and 'split' as the mechanics for the solution." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The best snippet is a near-perfect match for the question text and directly names the required method (.map) and logic (split).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the direct match is excellent, there is no explanation of 'lambda' syntax or how '[0]' indexes the result of a split.", + "missing_concepts": [ + "lambda syntax", + "indexing split results" + ], + "proposed_fix": "Add a snippet explaining that 'lambda x: x.split(...)[0]' is a concise way to take the first part of every string in a collection." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "proposal": "Expand the snippet text to include the full logic: 'The .map(lambda x: x.split(\"; \")[0]) method allows applying the split function to each element and taking the first part.'", + "why_helpful": "The current text cuts off at '(like spli'. Showing the full code ensures a student can confidently identify Option A without guessing 'lambda' syntax.", + "why_maybe_unnecessary": "The current text is already highly suggestive of the correct answer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:36:41Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q09", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q09", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-1", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "\"03/02/2013\" matches %m/%d/%Y and gives month 3, \"03.02.2013\" matches neither branch and becomes None, and \"03-02-2013\" matches %d-%m-%Y and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This snippet is a direct match for the question and includes an explanation of how the different date formats are parsed and which components correspond to the month." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Directly explains the logic of the code and the resulting values for each input string." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Helps a beginner understand the general structure of a function that iterates through a list and returns a new list based on conditions." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Provides context on how function calls and returns work in Python, helping trace the execution." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Contains the exact code logic and explains the interpretation of the strptime format codes (%m vs %d)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains the exact question with an explanation that breaks down the code's behavior for each input string.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective because one of them is a perfect match for the question. A minor gap exists in providing a general reference for datetime format codes.", + "missing_concepts": [ + "General table of datetime.strptime format codes (e.g., %m, %d, %Y, %b)" + ], + "proposed_fix": "Add a summary card or 'cheat sheet' snippet specifically for Datetime format directives." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a reference snippet for Datetime format strings: %Y (4-digit year), %y (2-digit year), %m (month), %d (day), %H (hour), %M (minute), %S (second).", + "why_helpful": "This would allow a student to solve any datetime parsing question, even if the specific question isn't in the database.", + "why_maybe_unnecessary": "The specific exam question snippet already provides the necessary interpretation for this particular task.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:36:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q10", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q10", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-2", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives the zero-based offset in days, and adding 1 converts it to the day number within the year. The other options either return or manipulate timedeltas incorrectly or use an invalid date.", + "code_context": "Example target behavior:\nday_of_year(datetime(2022, 2, 1))\n# returns 32" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This snippet explicitly explains the logic required: subtracting two datetime objects yields a timedelta, and the '.days' attribute must be accessed to get an integer difference." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly explains the relationship between datetime subtraction, timedelta objects, and the .days attribute." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Helps a zero-knowledge student recognize the basic 'def function_name(argument):' syntax used in the options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Provides the specific technical knowledge (timedelta and .days) to distinguish the correct answer from the distractors." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The sample final snippet contains a search text that almost perfectly mirrors the question's logic, explaining that subtraction results in a timedelta and that .days provides the integer needed.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover the core logic (timedelta/days), but don't explicitly state that datetime days must be 1-indexed (invalidating option D's day=0) or that you can't add an integer to a timedelta object directly (invalidating option B/C more strictly).", + "missing_concepts": [ + "datetime constructor constraints (day range 1-31)", + "timedelta arithmetic restrictions (cannot add int to timedelta)" + ], + "proposed_fix": "Add a small reference snippet or 'AI Common Question' about basic datetime and timedelta arithmetic rules." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining that 'datetime(year, month, day)' requires day to be at least 1, and that you cannot directly add an integer to a timedelta object (you must add another timedelta or convert to int first).", + "why_helpful": "It would allow a student to systematically eliminate options B, C, and D rather than just identifying A as plausible.", + "why_maybe_unnecessary": "The current 'best snippet' is so similar to the correct answer that most students will pick A regardless.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:37:22Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q11", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q11", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "8-dict_comprehension-1", + "question": "You have a list of strings called list_1, in which every element is unique.\n\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the dictionary comprehension that maps each string to its length. Option B creates a list, option C creates a set, and option D reverses the intended key-value relation.", + "code_context": "list_1 contains unique strings." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This snippet contains the exact same question text and explicitly identifies Option A as the correct answer, explaining that it is a standard dictionary comprehension." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Directly matches the question text and provides the correct answer with a brief explanation of the comprehension types." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Presents a functionally identical problem (mapping a list of strings to their lengths) and confirms Option A as the solution." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides additional context on creating dictionaries from existing list data, reinforcing the mapping concept." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Literal match for the question; sufficient on its own to identify the answer." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include a verbatim match for the exam question, including the options and the correct answer designation.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are excellent because they contain the exact question or identical logic. No gaps identified for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:37:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q12", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q12", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "8-list_comprehension-1", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\n\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[letter.upper() for letter in list_1 if letter.islower() else letter.lower()]", + "c": "[letter.lower() for letter in list_1 if letter.isupper()] + [letter.upper() for letter in list_1 if letter.islower()]", + "d": "[letter.capitalize() for letter in list_1 if not letter.iscapitalized()]" + }, + "correct": "a", + "explanation": "Option A flips the case of each letter while preserving the original order of the list. The other options either have invalid comprehension syntax, change the order, or use a non-existent string method.", + "code_context": "list_1 contains letters with mixed case." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "This snippet describes the exact same problem (flipping letter case in a list) and confirms that conditional logic within a code line is the correct approach, making it an almost direct answer key." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Direct conceptual match for the problem statement and mentions the use of conditional logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Mentions checking upper/lower case versions of letters, providing context that case sensitivity is a standard consideration in these types of problems." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Provides the necessary confirmation that case flipping in lists is a known problem solvable with conditional comprehension logic." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The best snippet is a direct analog of the question, providing both the goal and the logic (conditional comprehension) required to solve it. A student can match the 'flip case' intent directly to the snippet's description.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the snippet confirms the logic, it doesn't explicitly display the syntax pattern [X if condition else Y for item in list] vs [X for item in list if condition else Y], which is the primary technical distractor (Option A vs B).", + "missing_concepts": [ + "explicit ternary conditional syntax in list comprehensions" + ], + "proposed_fix": "Add a lecture snippet or reference card that explicitly shows the syntax for list comprehensions with if-else clauses (transformation) vs if-only clauses (filtering)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A syntax reference card for list comprehensions showing: 1. [f(x) for x in list if cond] (filtering) vs 2. [f(x) if cond else g(x) for x in list] (transformation).", + "why_helpful": "The question's main challenge is the syntax placement of the 'if-else' (Option A vs B). A direct syntax guide would make the choice trivial for a non-Python user by showing that 'if-else' must come before the 'for' keyword.", + "why_maybe_unnecessary": "The existing exam snippet already points to 'conditional logic' which might be enough for an intuitive student to pick the only syntactically plausible option (A).", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:38:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q13", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q13", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Basic logic", + "question": "Suppose you have three variables x, y, z as follows:\n\nx = 'x'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string 'x' is not equal to the integer 3 or the float 3.0, so the first and third comparisons are False. The integer 3 and float 3.0 are equal in Python, so the second comparison is True. The chained comparison is False because x == y is False.", + "code_context": "x = 'x'\ny = 3\nz = 3.0\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet is a near-perfect match for the question logic. Its explanation explicitly details the rules for string vs. number comparisons, integer vs. float equality (3 == 3.0), and the exact decomposition of chained comparisons (x == y == z)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Directly explains every component of the question's logic, including type-mismatch comparisons and chained equality." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Reinforces the concept that int 3 and float 3.0 are equal (x == y) while strings are not (x != z), providing a secondary example of the same cross-type comparison rules." + }, + { + "item_id": "aiq-5", + "rationale": "Useful for understanding how variables are assigned and compared across different types (int, float, string) in a multi-variable scenario." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet alone provides all three necessary rules: 1. 'str' == 'int/float' is False. 2. 'int' == 'float' is True if values match. 3. 'a == b == c' is evaluated as '(a == b) and (b == c)'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-13-w1-objects-and-names' contains an explanation that explicitly answers the exact logic required for all four lines of the code in the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets are excellent, especially the sample final snippet which covers the chained comparison logic which is usually the hardest part for beginners.", + "missing_concepts": [ + "Explicit definition of types (str, int, float) would be helpful as a reference, though the behavior is clear from the examples." + ], + "proposed_fix": "Add a summary card covering cross-type equality rules and chained comparison evaluation." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Conceptual Card: 'Comparison Rules by Type'. Rule 1: Integers and Floats are equal if they represent the same number (e.g., 3 == 3.0 is True). Rule 2: Strings are never equal to numbers (e.g., '3' == 3 is False). Rule 3: Chained comparisons (a == b == c) are treated as (a == b) AND (b == c).", + "why_helpful": "It abstracts the logic from the exam snippets into a clear set of rules that a student can apply to any similar question.", + "why_maybe_unnecessary": "The explanation in the sample final exam snippet already provides this information, though in a question-specific context.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:38:43Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q14", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q14", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Basic loop", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. In the first iteration, just take the previous number to be 0.\n\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e. only the sums).", + "options": { + "a": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "b": "i = 0\nwhile i <= 10:\n print(i + (i - 1))\n i += 1", + "c": "Both of the above", + "d": "Neither of the above" + }, + "correct": "a", + "explanation": "A keeps track of the previous number and prints each sum correctly from 1 + 0 through 10 + 9. B does not use the required previous-value logic and prints the wrong sums.", + "code_context": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "This snippet describes the exact logic and goal of the question (iterating 1-10, summing current and previous) and provides a direct contextual match, even though its internal explanation mistakenly identifies 'Option B' instead of 'Option A'." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "Identifies the core problem pattern and logic requirements." + }, + { + "item_id": "aiq-3", + "rationale": "Explicitly explains that 'stop' is excluded in range(), which is critical for a student to know that range(1, 11) targets the integers 1 to 10." + }, + { + "item_id": "ks-bddafc66a0", + "rationale": "Provides the basic syntax for 'for' loops and shows an example of updating a 'total' variable, which mirrors the 'previous' state-tracking pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "Problem-specific logic." + }, + { + "item_id": "aiq-3", + "rationale": "Understanding the range() function's boundary behavior." + }, + { + "item_id": "ks-bddafc66a0", + "rationale": "Basic for-loop syntax and variable initialization pattern." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the direct problem-match snippet (even with its label typo) and the 'range' explanation provides all the semantic components needed to identify why 'Option A' is correct (it starts at 1, goes to 10, and updates state at the end).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover the specific problem logic and the range boundary. However, the explanation in the best snippet has a typo (referring to B instead of A) which could be confusing for zero-knowledge students.", + "missing_concepts": [ + "Explicit state-tracking (updating a variable like 'previous' at the end of a loop)" + ], + "proposed_fix": "Add or edit a snippet to explicitly explain 'State Variables' in loops: why the update happens at the bottom and how it affects the next iteration." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "proposal": "Correct the snippet text to point to Option A and add a brief trace: 'In iteration 1: i=1, prev=0. After print, prev becomes 1. In iteration 2: i=2, prev=1...'", + "why_helpful": "Prevents confusion caused by the current typo and reinforces the 'state-tracking' mechanic.", + "why_maybe_unnecessary": "The student might infer the logic from the code options regardless of the snippet's letter label.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:39:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q15", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q15", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Basic scope", + "question": "Executing the following program will produce an error. Why?\n\ndef cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "options": { + "a": "Result is a local variable and cannot be referenced outside of the function", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "result is created inside the function, so it is local to cube and is not available at the top level where print(result) is executed.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "This snippet is a near-perfect match for the question, explicitly mentioning the 'cube' function and the variable 'result', and explaining that it cannot be accessed from the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Directly matches the specific code context (cube function, result variable) and logic of the question." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the formal conceptual rule for local vs. global scope, explaining that names defined inside a function are only known inside that function." + }, + { + "item_id": "manual-local-name", + "rationale": "Offers a clear, simple example showing that names (parameters or locals) fail when printed outside the function body." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Provides the direct answer to the identical pattern." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Supplies the underlying theoretical principle of scope." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-15-w2-conditions' contains a virtually identical question and explanation. Combined with the lecture note on scope (ks-2a6510492d), a student can easily deduce the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippet coverage is excellent. There is a direct match in the exam snippets and a clear conceptual explanation in the lecture snippets.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:39:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q16", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q16", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "List lambda", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\n\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "list_1[0](1, 2) returns 3 and list_1[1](1, 2) returns 2, so the expression becomes 3 ** 2, which is 9.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "This snippet is an exact duplicate of the target question, providing the identical code context, answer, and a clear breakdown of the lambda evaluation and exponentiation (3 ** 2 = 9)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "Directly answers the question with a full explanation of the logic." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Provides additional context for functions defined with the ** operator (n**2 and n**3), reinforcing that ** means exponentiation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows general list indexing and printing syntax, which helps a novice understand how items are accessed from a collection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "On its own, this snippet provides the exact question, the math involved, and the final answer." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One of the snippets is the exact question being asked, including the explanation of how lambda parameters are applied and the meaning of the exponentiation operator.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps exist for this specific question because the database contains the identical exam item. However, for a student with zero knowledge, a general summary of 'lambda' syntax would be beneficial for similar but non-identical questions.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:39:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q17", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q17", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "List logic", + "question": "You have the following function called main:\n\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat are the outputs of the following lines:\nmain([[], (), []])\nmain([[1], [2, 2], [3, 3, 3]])\nmain([[1], [2], [3]])", + "options": { + "a": "True\nTrue\nTrue", + "b": "True\nFalse\nTrue", + "c": "True\nFalse\nFalse", + "d": "False\nFalse\nTrue" + }, + "correct": "a", + "explanation": "For the first call, each element has length 0, so y becomes [True, True, True] and the comparison is True. In the second and third calls, each element has non-zero length, so y becomes [False, False, False] and the chained equality is also True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Crucially explains how chained equality (x == y == z) is evaluated as (x == y) and (y == z), which is the core logic of the return statement." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Explains chained equality evaluation (x == y == z) and boolean comparisons." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Provides an almost identical structural template: initializing an empty list, looping through an input list, using an if-condition, and appending results." + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Demonstrates the use of the len() function on collections like lists and sets to check for equality." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Clarifies the chained equality logic required to solve the return value." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Shows the list-building pattern (y = [], for loop, append) used in the question." + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Confirms len() is used to count elements in a collection." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets cover the code structure (loop/append), the usage of len(), and most importantly, the non-obvious evaluation of chained equality (x == y == z). A student can map these parts directly to the question logic.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is covered, there is no explicit mention that empty structures like [] or () have a length of 0, nor an explanation of list indexing (y[0]).", + "missing_concepts": [ + "Length of empty collections ([], (), {}) is 0", + "List indexing syntax (y[0], y[1]) for accessing elements" + ], + "proposed_fix": "Add a snippet demonstrating that len([]) is 0 and showing how to access the first element of a list using [0]." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'my_list = [True, False]; len([]); my_list[0] # Returns True'.", + "why_helpful": "This covers two minor gaps: that an empty list has length 0, and that [0] is used to retrieve the first item.", + "why_maybe_unnecessary": "A student might guess that 'empty' means 0 length and that indices start at 0 based on general logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:40:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q18", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q18", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "List loop", + "question": "How do you break a list into a list of lists, in which a sub-list consists of 3 values each?\n\nFor example, if the original list x is:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nthen how would you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:i + 3] for i in range(0, 7, 3)]", + "b": "y = [x[0::3] for i, enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of the above works" + }, + "correct": "a", + "explanation": "A slices the list into consecutive groups of three elements. B does not produce the required nested lists.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "This snippet contains the exact question and provides a step-by-step explanation of why Option A is correct, detailing the range generation (0, 3, 6) and the corresponding slice indices." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Directly answers the question and explains the slicing logic for partitioning a list." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Illustrates the [start:stop:step] slicing syntax, which helps a student understand the 'step' parameter used in the correct answer's range." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Provides additional examples of slicing and list manipulation, reinforcing the concept of extracting sub-parts of a sequence." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "The explanation within this snippet is enough for a student to match the logic of 'range' and 'slicing' to Option A in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-18-w2-conditions' is a direct match for the question and explicitly explains the mechanics of the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the direct answer. However, they assume the student understands the 'for i in ...' syntax of list comprehensions, even if the mapping to range values is explained.", + "missing_concepts": [ + "List comprehension syntax ([... for ... in ...])" + ], + "proposed_fix": "Add a foundational snippet explaining that list comprehensions create a new list by running an operation for every item in an iterable like range()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Core Concept' snippet for List Comprehensions: Syntax: [expression for item in iterable]. This creates a new list by applying 'expression' to each 'item' in the sequence (like range). Example: [x*2 for x in [1,2,3]] results in [2,4,6].", + "why_helpful": "It bridges the gap for students who see the range/slicing logic explained but don't recognize the structural 'wrapper' of the list comprehension.", + "why_maybe_unnecessary": "The direct explanation in the exam snippet might be enough for a student to simply pick the matching option without fully 'understanding' the loop.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:41:02Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q19", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q19", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-1", + "question": "You have to write a function called main that accepts a dictionary as an input argument. Both the keys and the values of the input are integers.\n\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary, whose keys are smaller than, or equal to, the output key in question.\n\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\n\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "b": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "c": "Both of the above works as intended", + "d": "None of the above work as intended" + }, + "correct": "c", + "explanation": "Option A builds cumulative sums over the sorted keys, and option B directly computes the sum of values whose keys are less than or equal to each output key. Both produce the intended dictionary values.", + "code_context": "Example target behavior:\nmain({5: 1, 2: 5, 4: 2})\n# returns a dictionary equal to {5: 8, 2: 5, 4: 7}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "Shows a function returning a dictionary where values are calculated using aggregate functions like sum(), which is core to both options." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Demonstrates dictionary construction with calculated values (total, min, max)." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Introduces the concept of filtering values when creating a dictionary, relevant to the 'if k <= output_key' logic in Option B." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary creation from a list of strings, helping with the syntax of 'd2[key] = value'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Syntax for returning dictionaries with calculated values." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Logic for conditional dictionary entry creation." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Context for accessing dictionary values by key for calculations." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the snippets show dictionary creation and sum(), they lack critical concepts: the sorted() function for keys (Option A), the list comprehension syntax [v for k,v in d.items()] (Option B), and the .items() method itself. A student with zero knowledge would not be able to verify if these specific Python constructs work.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing core syntax for dictionary iteration and sorting.", + "missing_concepts": [ + "sorted() function behavior on dictionary keys", + "List comprehension with filtering syntax", + "dictionary.items() method for key-value iteration", + "Cumulative/running total pattern in a loop" + ], + "proposed_fix": "Add a snippet demonstrating sorted(d.keys()) and a snippet showing a basic list comprehension used to filter and sum data." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'for key in sorted(prices.keys()): ...' and another showing 'sub_total = sum([val for key, val in d.items() if key < 10])'.", + "why_helpful": "This directly maps to the syntax used in Options A and B, allowing a student to recognize the patterns.", + "why_maybe_unnecessary": "If the goal is only to teach dictionary creation, existing snippets are okay, but for this specific logic question, they are inadequate.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:42:23Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q20", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q20", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-2", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) creates key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "This snippet is a verbatim match for the exam question, explicitly stating that d1 (from zip) and d2 (from enumerate) result in the same dictionary {1: 2, 2: 3, 3: 4, 4: 5}, thus making the comparison True." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Provides the direct answer to the exact code scenario and comparison logic described in the question." + }, + { + "item_id": "ks-65c4de2e9d", + "rationale": "Explains the fundamental rule that dictionaries are 'unordered for equality', which is the conceptual basis for why d1 == d2 evaluates to True even if constructed via different iterators." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Offers visual examples of dictionary values and keys being manipulated, helping a novice recognize the 'd[key] = value' pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Since this snippet explicitly contains the solution and the final state of the dictionaries for this specific question, it is sufficient on its own." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes a snippet that is a direct hit for the exact question being asked, providing the answer and the logic in one place.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets provide a 'shortcut' to the answer but don't explain the mechanics of 'zip' and 'enumerate' in a way that allows a student to solve a variation of the question (e.g., if the lists were different).", + "missing_concepts": [ + "The mechanical pairing process of zip(l1, l2).", + "The incremental counter behavior of enumerate(l, start)." + ], + "proposed_fix": "Add a foundational lecture snippet that defines zip and enumerate as pair-generating functions often used for dictionary population." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Iteration Helpers. Snippet: 'zip(l1, l2)' pairs elements by position: (l1[0], l2[0]), (l1[1], l2[1]). 'enumerate(l, start=0)' pairs index with value: (start, l[0]), (start+1, l[1]). These pairs are often used to populate dictionaries with d[key] = value.", + "why_helpful": "It allows a student to derive the result for any list content rather than just matching a specific example.", + "why_maybe_unnecessary": "The verbatim match in the existing exam snippets already solves this specific question perfectly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q21", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q21", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-3", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\n\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not key-value pairs, so `for key, value in d1:` does not work as intended. The other three options all sum the dictionary values and print the same result.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "This snippet is an exact match for the question logic and provides the specific explanation that iterating directly over a dictionary (for key, value in d1) only yields keys, causing a ValueError during unpacking." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Directly identifies the error in option (a) and explains why it differs from the others." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Provides the fundamental rules for dictionary iteration (.keys(), .values(), .items()), which validates options (b) and (c)." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the exact dictionary structure used in the question and demonstrates extracting values and keys as sequences." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Explains the failure mode of iterating directly without .items()." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Explains the correct syntax for the valid options." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions' contains the precise question and explanation, while 'ks-adb6d9f967' covers the underlying mechanics.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective. A minor gap exists regarding the explicit behavior of the 'sum()' function when applied directly to a dictionary view (option d).", + "missing_concepts": [ + "behavior of sum() on dict_values objects" + ], + "proposed_fix": "Add a snippet demonstrating that 'sum()' works on dictionary views just like it does on lists." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a knowledge snippet: 'Built-in functions and Dictionaries: Functions like sum(), min(), and max() can be applied directly to dictionary views. Example: result = sum(my_dict.values()) correctly totals all values.'", + "why_helpful": "This would explicitly cover option (d) in the question, ensuring a student doesn't have to guess if sum() works on .values().", + "why_maybe_unnecessary": "Option (a) is so clearly identified as an error by the best snippet that the student can identify it by elimination anyway.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q22", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q22", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-1", + "question": "You have the following string\nx = 'Amsterdam'\n\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method must be called on the string object itself, so `x.count('a')` is the correct form. In 'Amsterdam', there is one lowercase 'a', while the initial uppercase 'A' is not counted.", + "code_context": "x = 'Amsterdam'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "This snippet is a near-identical match to the exam question itself. it explicitly states that .count() is a string method requiring dot notation (x.count('a')) and confirms it is not a standalone function, directly answering the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Directly provides the answer and explains the syntax requirement for the count method." + }, + { + "item_id": "ks-ab66f3bab6", + "rationale": "Provides the general underlying principle: methods are called with dot notation (obj.method()), which explains why 'x.count()' is correct while 'count(x)' is not." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Identifies the specific method and syntax required for the string 'Amsterdam'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-22-w2-conditions' contains the exact question and its solution, while the lecture snippet explains the 'why' behind the syntax.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets are excellent for this specific question because it is a direct repeat from a sample exam.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:34Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q23", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q23", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-2", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "For option A, the function returns 6 + 7 + 8 + 9 = 30. For option B, it returns 1 + 4 + 9 + 16 = 30. Both calls therefore produce 30.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "This snippet is a near-perfect match for the target question, providing the exact logic (summing 6+7+8+9 and 1+4+9+16) and the correct answer (C)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Directly contains the logic and solution for the specific math/logic puzzle in the question." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Provides a structural template for passing a lambda as a 'condition' argument and calling it inside a loop, which mirrors the target code." + }, + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "rationale": "Explains the *args syntax (flexible arguments) and demonstrates iterating over them with a loop, which is essential for understanding the function's behavior." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Provides the direct answer and internal calculation logic." + }, + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "rationale": "Clarifies how *args works as a list-like iterable." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Demonstrates the syntax for defining and calling a lambda passed as a variable." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact exam question from a different year/sample. A student can match the '30' result and the calculation breakdown directly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is present, the snippets lack a concise 'definition' of lambda syntax (lambda x: ...) for someone with zero programming knowledge.", + "missing_concepts": [ + "Explicit definition of lambda syntax", + "Square operator (**2) clarification" + ], + "proposed_fix": "Add a conceptual snippet for 'Anonymous Functions (Lambda)' that explicitly states 'lambda x: x**2' means 'take x and return x squared'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Lambda and Operators' that explains: 1. lambda x: [expression] creates a small function. 2. ** is the power operator (e.g., 2**3 is 8). 3. *args allows passing any number of values as a list.", + "why_helpful": "It bridges the gap from 'pattern matching the answer' to 'understanding the code' for a true zero-knowledge student.", + "why_maybe_unnecessary": "The student can already find the answer by matching the '30' and the numbers in the intro_python_sample_final snippet.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:53Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q24", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q24", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-3", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\n\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C imports the module under the name `constants`, but then tries to access `math.pi`, where `math` is not defined. The other options all reference pi correctly and would print the correct area.", + "code_context": "Area formula: πr²" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This snippet is a direct match for the question logic. It explicitly explains that 'import math as constants' requires using 'constants.pi' and that 'math.pi' becomes unavailable, which is the exact reason option C is incorrect." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "Directly addresses the import aliasing ('import as') mechanic and why the original name is no longer defined." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains that 'print' is a function used to output arguments to the screen, which helps a novice understand what the code intends to do." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "While not directly about imports, it demonstrates the use of the '**2' operator for squaring numbers, confirming the math formula syntax." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "Provides the specific rule required to identify the incorrect option." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-24-w2-conditions' contains a verbatim explanation of the 'import as' concept applied to the math module and the circle area problem.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide a perfect match for the specific technical hurdle (module aliasing) and the general syntax (print, power operator).", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:45:32Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/exam_question_bank.json b/data/vision_exam_pipeline/exam_question_bank.json new file mode 100644 index 0000000..21e9dbc --- /dev/null +++ b/data/vision_exam_pipeline/exam_question_bank.json @@ -0,0 +1,5277 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T18:40:26Z", + "policy": { + "vision_only_question_capture": true, + "text_layer_extraction_forbidden": true, + "ocr_forbidden": true, + "human_review_checkpoint_required": true + }, + "canonical_exam_count": 7, + "duplicate_aliases": [ + { + "exam_id": "final-exam-solutions-for-python-programming-course-code-308088-308234", + "duplicate_of": "final-exam-solutions-for-python-programming-62oop21", + "title": "2022 Final Exam Duplicate Copy", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-solutions-for-python-programming-course-code-308088-308234.pdf" + } + ], + "page_manifest_path": "data/vision_exam_pipeline/page_manifest.json", + "exams": [ + { + "exam_id": "sample-final-plus-answers", + "title": "2025 Sample Final Plus Answers", + "group": "current-year", + "pdf_path": "../course_files_after_midterm/Sample Final plus answers.pdf", + "expected_questions": 24, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-01.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-02.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-03.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-04.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-05.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-06.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-07.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-08.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-09.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-10.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-11.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-12.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-13.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-14.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-15.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-16.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-17.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-18.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-19.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-20.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-21.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-22.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-23.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-24.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-25.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-26.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-27.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-28.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-29.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-30.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-31.png" + ], + "page_count": 31, + "duplicate_aliases": [], + "seed_sources": { + "legacy_assessment_payload_path": "data/import_payloads/post_midterm_assessments/sample_final_plus_answers.json", + "study_db_exam_label": "intro_python_sample_final_24_25", + "study_db_exam_source": "materials/post_midterm/Sample Final plus answers.pdf", + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review." + }, + "review_tracking": { + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "legacy_seeded_questions": 0, + "pending_vision_questions": 0 + }, + "extraction_status": "partial", + "questions": [ + { + "question_id": "sample-final-plus-answers-q01", + "number": 1, + "topic": "vehicle class defaults", + "question": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation.\nThe name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string \"land\".\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A correctly defines the constructor with `self`, stores both attributes on the instance, and gives `vehicle_mode` the default value `\"land\"`.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Question 1 option code is small in the rendered page and should be human-confirmed during merge review." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q02", + "number": 2, + "topic": "book rating output", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The stored review scores are 5, 3, and 3. Their average is 11 / 3 = 3.666..., and the method rounds that to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q03", + "number": 3, + "topic": "student grade formatting", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\nFor example, if\nstudents = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 75.\nBernard has received a grade of 80.\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']}. \")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {student['Grade']}. \")", + "c": "for student in students:\n print(f\"{student['Name']} has received a grade of \" + str(student[\"Grade\"]))", + "d": "for student, grade in students.items():\n print(f'{student} has received a grade of {grade}.')" + }, + "correct": "a", + "explanation": "Option A iterates through the list of dictionaries and prints each student's name together with that student's grade. The other options incorrectly call `.items()` on the list or use the wrong data access pattern.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-07.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Question 3 option text should be human-confirmed for exact spacing/punctuation around the printed sentence." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q04", + "number": 4, + "topic": "phone number formatting", + "question": "You need to write a function called format_phone_number that formats phone numbers.\nThe output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) at various places.\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A calls `replace` but does not store its result, so it returns the original unchanged string. The other options all build and return the digits without the dashes.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# should all return \"0205251400\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-09.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q05", + "number": 5, + "topic": "pandas even-row selection", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.9\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that looks like this, when printed:\n\n B\n2 8.2\n4 3.6\n6 8.4\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters the even-numbered row labels and keeps column `B` as a one-column DataFrame, matching the printed target. The other options use invalid indexing, select the wrong column/positions, or return a Series instead of the shown DataFrame.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-11.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q06", + "number": 6, + "topic": "pandas df2 derivation", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False).loc[:, [\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A would keep all five rows after sorting the index descending, so it would not produce the shown three-row df2. The other options can all produce rows 4, 3, and 2 with columns A, C, and D in the displayed order.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-13.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q07", + "number": 7, + "topic": "datetime month parser", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "`\"03/02/2013\"` is parsed with `%m/%d/%Y`, so its month is 3. `\"03.02.2013\"` matches neither separator rule and becomes `None`. `\"03-02-2013\"` is parsed with `%d-%m-%Y`, so its month is 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-15.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q08", + "number": 8, + "topic": "dictionary comprehension lengths", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the only dictionary comprehension that maps each string to its own length. Option B makes a list, Option C makes a set, and Option D reverses the intended key-value direction.", + "code_context": "list_1 = [ ... ]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-17.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q09", + "number": 9, + "topic": "Datetime parsing", + "question": "Take a look at the following code segment.\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "The first string contains `/`, so it is parsed as month/day/year and gives month 3. The second string contains neither `-` nor `/`, so it becomes `None`. The third contains `-`, so it is parsed as day-month-year and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-15.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q10", + "number": 10, + "topic": "Datetime day-of-year", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives a `timedelta`; taking `.days` and adding 1 makes January 1 equal to day 1. The other options either misuse `timedelta`, add an integer directly to a `datetime` difference, or use an invalid date.", + "code_context": "day_of_year(datetime(2022, 2, 1))\n# should return 32", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-16.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q11", + "number": 11, + "topic": "Dictionary comprehension", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Only option A is a dictionary comprehension with each string as the key and its length as the value. The others create a list, a set, or a dictionary with the mapping reversed.", + "code_context": "list_1 = [...]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-17.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q12", + "number": 12, + "topic": "Case swapping", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[x if x in 'abcdefghijklmnopqrstuvwxyz'.upper() else x.lower() for x in list_1]", + "c": "Both achieve what you want", + "d": "None achieves what you want" + }, + "correct": "a", + "explanation": "Option A explicitly checks whether each character is lowercase and flips the case accordingly. Option B leaves uppercase letters unchanged instead of converting them to lowercase.", + "code_context": "list_1 = [...]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-18.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q13", + "number": 13, + "topic": "Comparisons and types", + "question": "Suppose you have three variables x, y, z, as follows:\nx = '3'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string `'3'` is not equal to the integer `3`, while `3 == 3.0` is `True`. The chained comparison `x == y == z` means `(x == y) and (y == z)`, so it is `False`.", + "code_context": "x = '3'\ny = 3\nz = 3.0", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-19.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q14", + "number": 14, + "topic": "Loops", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. (In the first iteration, just take the previous number to be 0.)\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e.: only the sums).", + "options": { + "a": "i = 0\nwhile i <= 10:\n print(i + (i-1))\n i += 1", + "b": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "b", + "explanation": "Option B correctly tracks the previous number and starts the loop at 1, producing the required sums. Option A starts at 0 and prints `-1` on the first iteration, so it does not match the specification.", + "code_context": "# target outputs: 1, 3, 5, ..., 19", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-20.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q15", + "number": 15, + "topic": "Functions and scope", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "Result is a local name and cannot be referenced outside of the function.", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "`result` is defined inside `cube`, so it exists only within the function scope. The line `print(result)` is outside the function, where that local name is not defined.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-21.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q16", + "number": 16, + "topic": "Lambda functions", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "The first lambda returns `1 + 2 = 3`, the second returns `1 * 2 = 2`, and `3 ** 2` equals `9`.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-22.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q17", + "number": 17, + "topic": "Empty-sequence equality chain", + "question": "You have the following function called main:\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat will be printed by the following lines:\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))", + "options": { + "a": "True\nFalse\nFalse", + "b": "False\nFalse\nTrue", + "c": "True\nFalse\nTrue", + "d": "True\nTrue\nTrue" + }, + "correct": "d", + "explanation": "The first call builds [True, True, True], the second call builds [False, False, False], and the third call also builds [False, False, False]. In all three cases the chained equality compares three identical booleans, so each printed result is True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-23.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q18", + "number": 18, + "topic": "List chunking into sublists", + "question": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nFor example:\nIf you have the original list x as:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nHow do you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:(i + 3)] for i in range(0, 7, 3)]", + "b": "y = [x[i[0]::3] for i in enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "a", + "explanation": "Option A slices the list in chunks of length 3 starting at indices 0, 3, and 6, which produces the three required sublists in order.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-24.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q19", + "number": 19, + "topic": "Dictionary running totals", + "question": "You have to write a function called main that accepts a dictionary as an input argument.\nBoth the keys and the values of the input are integers.\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary whose keys are smaller than or equal to the output key in question.\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "b": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "c": "Both of the above work as intended", + "d": "None of the above works as intended" + }, + "correct": "c", + "explanation": "The first program computes each output value by summing all input values whose keys are less than or equal to the current key. The second program accumulates values in ascending key order, which yields the same running totals for each key.", + "code_context": "main({5: 1, 2: 5, 4: 2})\n# expected result:\n# {5: 8, 2: 5, 4: 7}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-25.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q20", + "number": 20, + "topic": "Dictionary equality with zip and enumerate", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) produces key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same key-value pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-27.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The preceding rendered page is an empty feedback/interstitial page; the verified question appears on page-27.png." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q21", + "number": 21, + "topic": "Dictionary iteration semantics", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not (key, value) pairs, so `for key, value in d1:` is invalid. The other three variants all sum the dictionary values correctly.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-28.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q22", + "number": 22, + "topic": "String count method", + "question": "You have the following string\nx = 'Amsterdam'\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method `count` must be called on the string object itself. `x.count('a')` returns 1 for the lowercase 'a' in 'Amsterdam'.", + "code_context": "x = 'Amsterdam'", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-29.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q23", + "number": 23, + "topic": "Higher-order function returning 30", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "The first call returns (1+5)+(2+5)+(3+5)+(4+5)=30, and the second returns 1^2+2^2+3^2+4^2=30. Both produce the requested result.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-30.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "sample-final-plus-answers-q24", + "number": 24, + "topic": "Circle area imports and aliases", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C aliases the module as `constants`, so `math.pi` is not defined there. The other three options reference pi correctly.", + "code_context": "# area formula\n# pi * r ** 2", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-31.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + } + ], + "blocked_questions": [] + }, + { + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "title": "2022 Final Exam", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-solutions-for-python-programming-62oop21.pdf", + "expected_questions": 24, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-02.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-03.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-04.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-05.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-06.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-07.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-08.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-09.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-10.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-11.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-12.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-13.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-14.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-15.png" + ], + "page_count": 15, + "duplicate_aliases": [ + { + "exam_id": "final-exam-solutions-for-python-programming-course-code-308088-308234", + "duplicate_of": "final-exam-solutions-for-python-programming-62oop21", + "title": "2022 Final Exam Duplicate Copy", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-solutions-for-python-programming-course-code-308088-308234.pdf" + } + ], + "seed_sources": { + "legacy_assessment_payload_path": "data/import_payloads/post_midterm_assessments/final-exam-solutions-for-python-programming-62oop21.json", + "study_db_exam_label": "Test Exam 07-06-22", + "study_db_exam_source": "materials/post_midterm/practice_exams_previous_years/final-exam-solutions-for-python-programming-62oop21.pdf", + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review." + }, + "review_tracking": { + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "legacy_seeded_questions": 0, + "pending_vision_questions": 0 + }, + "extraction_status": "partial", + "questions": [ + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q01", + "number": 1, + "topic": "OOP Fundamentals", + "question": "Take a look at the following class definition.\n\nclass Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nGiven the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\nWhy?", + "options": { + "a": "The first argument (my_flight) should not have been passed to the set_date method in Code line 2.", + "b": "The capacity of the flight is not specified as an argument in Code line 1.", + "c": "The argument self is missing in Code line 1.", + "d": "The date string passed as an argument in Code line 2 represents an invalid date." + }, + "correct": "a", + "explanation": "set_date is an instance method, so Python passes self automatically. Passing my_flight explicitly adds an extra argument and causes the error.", + "code_context": "class Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\")\nmy_flight.set_date(my_flight, \"29-02-2022\")", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-02.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q02", + "number": 2, + "topic": "OOP Fundamentals", + "question": "You have the following definition for a Book class.\n\nclass Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)\n\nSuppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book. The compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?", + "options": { + "a": "def compare(self, other):\n avg_better = self.average_score() > other.average_score()\n no_fewer_reviews = self.num_reviews() >= other.num_reviews()\n if avg_better and no_fewer_reviews:\n return self.title\n elif not avg_better:\n return other.title\n else:\n return None", + "b": "def compare(self, other):\n for first, second in [(self, other), (other, self)]:\n avg_better = first.average_score() > second.average_score()\n no_fewer_reviews = first.num_reviews() >= second.num_reviews()\n if avg_better and no_fewer_reviews:\n return first.title\n return None", + "c": "Both methods above compare the book objects as intended.", + "d": "Neither of the two methods above compare the book objects as intended." + }, + "correct": "b", + "explanation": "B checks whether either book is better than the other and returns that title, otherwise it returns None. A can incorrectly return the other book even when neither book is better.", + "code_context": "class Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-02.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q03", + "number": 3, + "topic": "Strings", + "question": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?", + "options": { + "a": "def get_tld(url):\n url_1 = url.split(\".\")[-1]\n return url_1.split(\"/\")[0]", + "b": "def get_tld(url):\n url_1 = url.split(\"//\")[1]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]", + "c": "def get_tld(url):\n return url.split(\"//\")[1].split(\"/\")[0].split(\".\")[-1]", + "d": "def get_tld(url):\n url_1 = url[url.find(\"www\") + 2:]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]" + }, + "correct": "a", + "explanation": "A splits on the last dot first, which leaves the page extension rather than the domain. The other options isolate the host name first and then extract the final dot-separated part.", + "code_context": "def get_tld(url):\n # Extract the top-level domain from a URL string", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-03.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q04", + "number": 4, + "topic": "Strings", + "question": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "def is_anagram(word_1, word_2):\n return sorted(list(word_1.replace(\" \", \"\").lower())) == sorted(list(word_2.replace(\" \", \"\").lower()))", + "b": "def is_anagram(word_1, word_2):\n return word_1.replace(\" \", \"\").lower().sort() == word_2.replace(\" \", \"\").lower().sort()", + "c": "def is_anagram(word_1, word_2):\n return list(word_1.replace(\" \", \"\").lower()).sort() == list(word_2.replace(\" \", \"\").lower())", + "d": "def is_anagram(word_1, word_2):\n return sorted(list(word_1)).replace(\" \", \"\").lower() == sorted(list(word_2)).replace(\" \", \"\").lower()" + }, + "correct": "a", + "explanation": "A removes spaces, lowercases both strings, and compares the sorted letters. The other options misuse sort() or apply string operations to list objects in the wrong order.", + "code_context": "def is_anagram(word_1, word_2):\n # Compare the same letters in normalized, sorted form", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-03.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q05", + "number": 5, + "topic": "Pandas", + "question": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "s.map((s - s.mean())**2)", + "b": "(s - s.mean())**2", + "c": "s.map(lambda x: (x - s.mean())**2)", + "d": "(s - s.mean()).map(lambda x: x**2)" + }, + "correct": "a", + "explanation": "A is not the right way to apply the squared-difference expression to each element of the Series. B, C, and D all produce the desired squared differences.", + "code_context": "# s is a pandas Series of floats", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-04.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q06", + "number": 6, + "topic": "7-pandas-2", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the difference of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] - df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x - df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\"] - df.columns[\"B\"]", + "d": "df[\"C\"] = df.apply(df[\"A\"] - df[\"B\"])" + }, + "correct": "a", + "explanation": "Subtracting one numeric Series from another directly creates the elementwise difference needed for column C.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q07", + "number": 7, + "topic": "7-pandas-3", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 8.7 4.6 9.5 7.0\n2 7.3 1.5 6.3 7.1\n3 4.3 9.0 2.9 3.3\n4 4.8 2.5 5.1 3.0\n5 1.6 1.4 6.7 3.5\n6 2.4 3.7 7.6 1.3\n\nSuppose that you'd like to create a new Series that only contains those elements of column \"D\" of df that are smaller than 5.0. So the Series should look like this, when printed:\n\n3 3.3\n4 3.0\n5 3.5\n6 1.3\nName: D, dtype: float64\n\nWhich of the following code lines will not achieve what you want?", + "options": { + "a": "df.loc[2:6, df.columns[-1]]", + "b": "df.loc[df[\"D\"] < 5, \"D\"]", + "c": "df.loc[3:6, \"D\"]", + "d": "df.iloc[2:6, 3]" + }, + "correct": "a", + "explanation": "Option A slices rows 2 through 6 from the last column but does not filter out values that are 5.0 or larger, so it includes values that should not be in the result.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q08", + "number": 8, + "topic": "7-pandas-4", + "question": "You have two DataFrames: df1 and df2. They look like this when printed:\n\nprint(df1)\n\n Age Height Female City Language\n0 23 167 True Berlin German\n1 36 175 True Frankfurt German\n2 17 182 False Antwerpen Dutch\n3 25 177 True Eindhoven Dutch\n4 36 178 False Lyon French\n5 52 185 False Basel German\n6 46 168 True Innsbruck German\n\nprint(df2)\n\n Age Height Female City Language\n5 52 185 False Basel German\n4 36 178 False Lyon French\n1 36 175 True Frankfurt German\n6 46 168 True Innsbruck German\n0 23 167 True Berlin German\n\nWhich of the following code segments could have created df2 from df1?", + "options": { + "a": "df1.loc[df1[\"Language\"].isin([\"French\", \"German\"])].sort_values(\"Height\", ascending=False)", + "b": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_values(\"Age\", ascending=False)", + "c": "df1.loc[~df1[\"Language\"].isin([\"Dutch\"]), [\"Age\", \"Height\", \"City\", \"Language\"]].sort_index(ascending=False)", + "d": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_index(axis=1)" + }, + "correct": "a", + "explanation": "Option A filters out the Dutch rows and then sorts the remaining rows by Height in descending order, matching df2 exactly.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q09", + "number": 9, + "topic": "8-comprehensions-1", + "question": "You have a list of mountain peaks and their heights in meters, all formatted as \"[PEAK NAME]: [HEIGHT]m\". For example, a few elements of the list are:\n\"Denali: 6,190m\", \"Aconcagua: 6,961m\", \"Kilimanjaro: 5,895m\", ...\n\nAs you can see, the comma (\",\") is used as a thousand separator in the height. The list is called mountains.\n\nYou'd like to create a dictionary called peaks from the mountains list. The peak names would be the keys, and the corresponding integer values. Continuing the example above, a few key-value pairs of the peaks dictionary should be:\n\"Denali\": 6190, \"Aconcagua\": 6961, \"Kilimanjaro\": 5895, ...\n\nWhich of the following two code segments achieves what you want?", + "options": { + "a": "peaks = {peak.split(\":\")[0]: int(peak.split(\": \")[1][:-1].replace(\",\", \"\")) for peak in mountains}", + "b": "names = [peak.split(\":\")[0] for peak in mountains]\nheights = [int(peak.split(\": \")[1].replace(\",\", \"\").replace(\"m\", \"\")) for peak in mountains]\npeaks = dict(zip(names, heights))", + "c": "Both code segments above achieve the intended outcome.", + "d": "Neither of the two code segments above achieves the intended outcome." + }, + "correct": "c", + "explanation": "Both solutions strip off the trailing m, remove the thousands separator, convert the height to an integer, and pair each mountain name with its numeric height.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q10", + "number": 10, + "topic": "8-comprehensions-2", + "question": "You have a dictionary called grades, in which the keys are unique student ID's (as strings) and the corresponding values are each student's Python course grades (as floats).\n\nYou'd like to create another dictionary called grade_curve, in which the keys are the 18 possible Dutch course grades (1.0, 1.5, 2.0, ..., 10) as floats, and the corresponding (integer) values are the number of students in grades who have that particular grade.\n\nTake a look at the following code segment to create the grade_curve dictionary.\n\ndutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0,\n 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}\n\nDo you think this code segment will always work as intended? If not, then why not?", + "options": { + "a": "Yes, the code will always work as intended.", + "b": "The code will not work as intended if there are certain grades that no student has received. That will lead to an error in constructing the dictionary comprehension.", + "c": "The code will not work as intended, because the keys of the grades dictionary are not used in the list comprehension inside the sum function.", + "d": "The code will not work as intended, because including a list comprehension inside a dictionary comprehension will lead to a Python syntax error." + }, + "correct": "a", + "explanation": "The inner comparison list produces True and False values for every grade entry, and sum counts the matches, including zero when no student received that grade.", + "code_context": "dutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q11", + "number": 11, + "topic": "8-datetime-1", + "question": "What does the following code segment print to the screen?\n\nfrom datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "options": { + "a": "26-03-2020", + "b": "04-24-2020", + "c": "15-04-2020", + "d": "05-14-2020" + }, + "correct": "a", + "explanation": "The string is parsed as 5 April 2020 using month.day.year format, and subtracting 10 days yields 26 March 2020, which is then formatted as day-month-year.", + "code_context": "from datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q12", + "number": 12, + "topic": "8-datetime-2", + "question": "Suppose you have the following definition for a Meeting class, which records basic information about meetings in a calendar application.\n\nYou would like to add a method called lunch_meeting to this class, which returns a boolean value indicating whether there is any overlap between the official lunchtime (12:30 - 13:00) and the time of the meeting.\n\nFor example, if you construct a Meeting object as:\nmy_meeting = Meeting('Ask for salary raise', \"25-05-2022\", start_time='12:00', length=45)\nthen the method call:\nmy_meeting.lunch_meeting()\nshould return the boolean value True.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = lunch_start + timedelta(minutes=30)\n return self.start < lunch_end and self.end > lunch_start", + "b": "def lunch_meeting(self):\n return self.start < \"13:00\" and self.end > \"12:30\"", + "c": "def lunch_meeting(self):\n return start_time <= \"13:00\" and start_time + length > \"12:30\"", + "d": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = datetime(self.date.year, self.date.month, self.date.day, 13, 0)\n return self.start >= lunch_end or self.end <= lunch_start" + }, + "correct": "a", + "explanation": "Option A constructs the lunch interval on the same date and uses the standard interval-overlap check. The other options compare datetimes to strings, reference names that are not in scope, or use the non-overlap condition instead.", + "code_context": "from datetime import datetime, timedelta\n\nclass Meeting:\n def __init__(self, topic, date, start_time=\"09:00\", length=30):\n self.topic = topic\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day,\n int(start_time.split(':')[0]), int(start_time.split(':')[1]))\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q13", + "number": 13, + "topic": "Basic logic 2", + "question": "Suppose you have a variable x which contains a list of tuples, as follows:\n\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nChoose the correct output for the following line of code.\n\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "options": { + "a": "True", + "b": "False", + "c": "NameError", + "d": "SyntaxError" + }, + "correct": "a", + "explanation": "The left-hand side is 2 * 3 = 6 and the right-hand side is 8 - 2 = 6, so the comparison evaluates to True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q14", + "number": 14, + "topic": "Basic loop 2", + "question": "Which of the following code segments will print every even number between 0 and 20 (including 0 and 20) to the screen?", + "options": { + "a": "for i in range(0, 20):\n if i % 2 == 0:\n print(i)", + "b": "i = 0\nwhile i <= 20:\n if i % 2 == 0:\n print(i)\n i += 1", + "c": "for i in list(range(0, 20)):\n print(i if i % 2 == 0 else None)", + "d": "i = 0\nwhile i < 21:\n print(i)\n i += 1" + }, + "correct": "b", + "explanation": "Option B checks every integer from 0 through 20 inclusive and prints only the even ones. Option A never reaches 20, option C also prints None for odd numbers, and option D prints every number.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q15", + "number": 15, + "topic": "Basic scope 2", + "question": "Choose the correct statement about the program below:", + "options": { + "a": "a is a global variable. b, c, d are local variables.", + "b": "a, b are global variables. c, d are local variables.", + "c": "a, b, c, d are global variables.", + "d": "a, c, d are global variables. b is a local variable." + }, + "correct": "a", + "explanation": "`a` is defined at module level, so it is global. `b` is local to `outer`, and `c` and `d` are local to `inner`.", + "code_context": "a = 1\ndef outer(b):\n b = 2\n def inner(c):\n d = 3\n return a + c + d\n return inner(4) + b", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q16", + "number": 16, + "topic": "final-dictionary-1", + "question": "You have to write a function called main, which takes a list of unique integers as an argument and returns a dictionary.\n\nThe output dictionary should consist of all key-value pairs for which the key is an element of the input list and the value is the next element of the input list. When there is no \"next element\" any more, leave the key-value pair out of the dictionary.\n\nFor example, if your function is called as:\nmain([1, 3, 2, 4])\nthen it should return the dictionary:\n{1: 3, 3: 2, 2: 4}\n\nWhich of the following programs work(s) according to the requirements?", + "options": { + "a": "def main(l1):\n result = {}\n index = 0\n while True:\n index = index + 1\n if index >= len(l1):\n break\n else:\n result[l1[index]] = l1[index + 1]\n return result", + "b": "def main(l1):\n result = {}\n for index, value in zip(l1[:-1], l1[1:]):\n result[index] = value\n return result", + "c": "Both programs work as required", + "d": "Neither of the two programs works as required" + }, + "correct": "b", + "explanation": "Option B correctly zips each element with the following element and builds the required dictionary. Option A starts at index 1 and eventually tries to access past the end of the list.", + "code_context": "main([1, 3, 2, 4])\n# should return {1: 3, 3: 2, 2: 4}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q17", + "number": 17, + "topic": "final-dictionary-2", + "question": "What will be printed by the following program?", + "options": { + "a": "True", + "b": "False", + "c": "An error message", + "d": "None" + }, + "correct": "a", + "explanation": "Dictionary equality compares key-value contents rather than insertion order. Since both dictionaries contain the same pairs, the comparison prints True.", + "code_context": "d1 = {1: 5, 4: 6}\nd2 = {4: 6, 1: 5}\nprint(d1 == d2)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q18", + "number": 18, + "topic": "final-dictionary-3", + "question": "d1 = {1: 2, 2: 1}\n\nThe following code segments all print exactly the same output, except for one. Which one?", + "options": { + "a": "result = 1\nfor x in d1.values():\n result *= x\nprint(result)", + "b": "result = -1\nfor x in d1.keys():\n result += d1[x]\nprint(result)", + "c": "result = 4\nfor x in d1.items():\n result = result // x[1]\nprint(result)", + "d": "result = -4\nfor x in d1:\n result /= d1[x]\nprint(result)" + }, + "correct": "d", + "explanation": "A, B, and C all print 2. Option D uses true division starting from -4, so it prints -2.0 instead, making it the odd one out.", + "code_context": "d1 = {1: 2, 2: 1}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q19", + "number": 19, + "topic": "final-functions-1", + "question": "Suppose that you have a string called s1, which contains several letters. The letter \"x\" and the letter \"y\" occur exactly once in the string, and \"x\" always precedes \"y\".\n\nYou'd like to print out a string that looks just like s1, except that the letters \"x\" and \"y\" should be swapped.\n\nFor example, if:\ns1 = \"axbyc\"\nthen you'd like to print:\naybxc\n\nReminder: The replace string method has a third argument, which allows you to specify the maximum number of replacements you want to make, counting from left to right.", + "options": { + "a": "s1 = s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "b": "s1 = s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)", + "c": "s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "d": "s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)" + }, + "correct": "b", + "explanation": "Option B first changes the single y to x, then changes the first x from left to right back to y, which swaps the two letters. Options C and D do not assign the new string back to s1, and A changes the first replacement back incorrectly.", + "code_context": "s1 = \"axbyc\"\n# desired printed result: aybxc", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option D's trailing `print(s1)` line is implied by the rendered pattern but should be human-confirmed from the source page." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q20", + "number": 20, + "topic": "final-functions-2", + "question": "Take a look at the following function definition.\n\nWhat will be returned by the following function call:\nglue(a='e', b='d')", + "options": { + "a": "ab", + "b": "cd", + "c": "ba", + "d": "dc" + }, + "correct": "c", + "explanation": "The function iterates over the keyword names in insertion order (`a`, then `b`) and prepends each key to the current result. Starting from the empty string, that produces `a`, then `ba`.", + "code_context": "def glue(**kwargs):\n result = ''\n for el in kwargs.keys():\n result = el + result\n return result", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q21", + "number": 21, + "topic": "final-functions-3", + "question": "Take a look at the following function definition.\n\nWhat will be printed to the screen by the following code?\nprint(tester())", + "options": { + "a": "1", + "b": "-1", + "c": "0", + "d": "None" + }, + "correct": "a", + "explanation": "The default argument is `0`, which satisfies the non-negative condition, so the function returns `1` and `print` outputs `1`.", + "code_context": "def tester(i1 = 0):\n if i1 >= 0:\n return 1\n\n if i1 < 0:\n return -1", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q22", + "number": 22, + "topic": "List lambda 2", + "question": "Assume that you have a variable called x, which contains a list of integers.\n\nWhich of the following code segments will create another list that has every element of x multiplied by 2?\n\nFor example, if\nx = [1, 2, 3, 4, 5]\nthen which of the following code segments will result in the list:\n[2, 4, 6, 8, 10]", + "options": { + "a": "list(map(lambda i : i * 2, x))", + "b": "[(lambda i : i * 2)(item) for item in x]", + "c": "y = lambda i : i * 2\n[y(i) for i in x]", + "d": "All three code segments would work as intended" + }, + "correct": "d", + "explanation": "Each option constructs the doubled list correctly: `map` with a lambda, an immediately called lambda inside a list comprehension, and a named lambda used inside a list comprehension all apply `i * 2` to every element of `x`.", + "code_context": "x = [1, 2, 3, 4, 5]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q23", + "number": 23, + "topic": "List logic 2", + "question": "Which of the following programs creates a new list y, in which the elements are those elements of list x that are equal to their indices?\nYou can assume x consists of unique integers.\n\nFor example, if:\nx = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\nthen the program should create a new list y such that:\ny = [0, 3, 6, 7, 8, 10]", + "options": { + "a": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(i)", + "b": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(j)", + "c": "y = [i for i in x if i == x.index(i)]", + "d": "All three programs would work as intended" + }, + "correct": "d", + "explanation": "In A and B, whenever `i == j`, appending either `i` or `j` gives the same value because the index equals the element. In C, `x.index(i)` returns the position of `i`, so the comprehension keeps exactly the elements equal to their indices. Therefore all three programs work.", + "code_context": "x = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\n# target result:\ny = [0, 3, 6, 7, 8, 10]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q23-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q24", + "number": 24, + "topic": "List loop 2", + "question": "Assume that you have a list called x, which is a list of multiple sub-lists containing integers.\n\nWhich of the following programs will create a new list y that is equal to the sub-list of x whose sum of elements is the highest?\n\nYou can assume that the sum of elements in each sub-list is a different number, so that there is only one that is the highest.\n\nFor example, if:\nx = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\nthen y should be:\ny = [8, 20, 300]", + "options": { + "a": "y = max(x)", + "b": "z = []\nfor i in x:\n z.append(sum(i))\ny = x[z.index(max(z))]", + "c": "x.sort()\ny = x[-1]", + "d": "y = [i for i in x if sum(i) == max(x)]" + }, + "correct": "b", + "explanation": "Option B computes the sum of each sub-list, finds the position of the largest sum, and then returns the corresponding original sub-list. The other options compare lists lexicographically or compare a numeric sum against `max(x)`, which is a list.", + "code_context": "x = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\n# target result:\ny = [8, 20, 300]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q23-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ], + "blocked_questions": [] + }, + { + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "title": "2023 Trial Final Study Guide", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-study-guide-trial-python-basics-2023.pdf", + "expected_questions": 24, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-02.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-03.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-04.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-06.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-07.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-08.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-09.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-10.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-11.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-12.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-13.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-14.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-15.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-16.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-17.png" + ], + "page_count": 17, + "duplicate_aliases": [], + "seed_sources": { + "legacy_assessment_payload_path": "data/import_payloads/post_midterm_assessments/final-exam-study-guide-trial-python-basics-2023.json", + "study_db_exam_label": "Trial final - Introduction to Python - 22/23", + "study_db_exam_source": "materials/post_midterm/practice_exams_previous_years/final-exam-study-guide-trial-python-basics-2023.pdf", + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review." + }, + "review_tracking": { + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "legacy_seeded_questions": 0, + "pending_vision_questions": 0 + }, + "extraction_status": "partial", + "questions": [ + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q01", + "number": 1, + "topic": "1_Basics_Logic_2", + "question": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\n- If they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\n- If they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?", + "options": { + "a": "if destination in europe:\n print('No passport needed. Bring your ID card.')\nelse:\n print('Please bring your passport.')", + "b": "if destination in europe:\n return 'No passport needed. Bring your ID card.'\nelif destination not in europe:\n return 'Please bring your passport.'", + "c": "for country in europe:\n if destination = country:\n print('No passport needed. Bring your ID card.')\n else:\n print('Please bring your passport.')", + "d": "for country in europe:\n if destination != country:\n return 'Please bring your passport.'\n else:\n return 'No passport needed. Bring your ID card.'" + }, + "correct": "a", + "explanation": "Option A directly checks whether destination is in the list of European countries and prints the correct message in each case. The other options either use the wrong control flow or invalid syntax.", + "code_context": "europe = [...]\ndestination = ...", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q02", + "number": 2, + "topic": "1_Basics_Scope_3", + "question": "Calling the function func_10 will produce an error. Which line of the following code segment produces the error?", + "options": { + "a": "'var_2 = var_1 * var'\nThis line produces the error because func_2() was not called and assigning the value to var_1, thus var_1 was referenced before being defined.", + "b": "'var_1 = var * 2'\nThis line produces the error because Python is confused about which value var should have.", + "c": "'def func_2(var):'\nThis line produces the error because the name var is already used for the argument of func_1() and cannot be used again as the name of the argument for func_2().", + "d": "'return var_2'\nThis line produces the error because one function cannot return two outputs." + }, + "correct": "a", + "explanation": "The inner function func_2 is defined but never called, so var_1 is never assigned before the line var_2 = var_1 * var tries to use it.", + "code_context": "def func_1(var):\n def func_2(var):\n var_1 = var * 2\n return var_1\n var_2 = var_1 * var\n return var_2", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q03", + "number": 3, + "topic": "1_Basics_Variables_1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[str, int, NoneType, bool, float, str, dict]", + "b": "[str, int, NoneType, bool, float, bool, dict]", + "c": "[str, int, NoneType, bool, float, str, list]", + "d": "[str, float, NoneType, bool, int, str, dict]" + }, + "correct": "a", + "explanation": "The function appends the type of each element in the input list in order: string, integer, NoneType, boolean, float, string, and dictionary.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n list_2.append(type(item))\n return list_2\n\nmain(['abc', 0, None, True, 123.456, 'False', {}])", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q04", + "number": 4, + "topic": "2-dictionaries - comprehension - 1", + "question": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\n\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97", + "options": { + "a": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou'}", + "b": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou' if vowel in 'aeiou'}", + "c": "Both of the code segments work correctly.", + "d": "Neither of the code segments work correctly." + }, + "correct": "c", + "explanation": "Both comprehensions produce the same dictionary because the extra condition in option B is always true for characters drawn from 'aeiou'.", + "code_context": "print(vowels_ASCII)\n# expected: {'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-04.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q05", + "number": 5, + "topic": "2-dictionaries - manipulation - 1", + "question": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = (goals1, goals2, goals3)", + "b": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = [goals1 + goals2 + goals3]", + "c": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = [goals1, goals2, goals3]", + "d": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = (goals1, goals2, goals3)" + }, + "correct": "a", + "explanation": "Option A uses enumerate with start=1 to create the correct match-number keys and stores each triple of goal counts as a tuple. The other options either use the wrong value shape or start indexing from 0.", + "code_context": "player1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\nprint(match_goals)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Options C and D are small in the rendered page and should be human-confirmed if exact bracket style matters." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q06", + "number": 6, + "topic": "2-dictionaries - slicing - 1", + "question": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?", + "options": { + "a": "sales_subset = [monthly_sales[key] for key in list(monthly_sales.keys())[:3]]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "b": "sales_subset = monthly_sales[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "c": "sales_subset = list(monthly_sales.items())[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "d": "sales_subset = monthly_sales['January':'March']\naverage_sales = sum(sales_subset.values()) / len(sales_subset)\nprint(average_sales)" + }, + "correct": "a", + "explanation": "Option A first collects the values for the first three keys into a list and then computes the average correctly. The other options attempt unsupported dictionary slicing or try to sum tuples instead of numeric values.", + "code_context": "monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q07", + "number": 7, + "topic": "2-list - comprehension - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "[1, 4, 3, 8, 5]", + "b": "[2, 4, 6, 8, 10]", + "c": "[1, 2, 3, 4, 5]", + "d": "[2, 2, 6, 4, 10]" + }, + "correct": "a", + "explanation": "The list comprehension doubles only the even numbers and leaves the odd numbers unchanged, so the result is [1, 4, 3, 8, 5].", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x * 2 if x % 2 == 0 else x for x in numbers]\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q08", + "number": 8, + "topic": "2-list - manipulation - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "['10a', '30c']", + "b": "[10, 20, 30, 40]", + "c": "['a', 'b', 'c', 'd']", + "d": "['10a', '20b', '30c', '40d']" + }, + "correct": "a", + "explanation": "The loop keeps only even indices from enumerate(list1), so it uses indices 0 and 2 and appends the concatenated strings '10a' and '30c'.", + "code_context": "list1 = [10, 20, 30, 40]\nlist2 = ['a', 'b', 'c', 'd']\n\nresult = []\n\nfor index, value in enumerate(list1):\n if index % 2 == 0:\n result.append(str(value) + list2[index])\n\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q09", + "number": 9, + "topic": "2-list - slicing - 2", + "question": "Suppose you have a list called mylist. You want to extract every third element starting from index 1 (inclusive) to the last index (inclusive) from that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\n\nthen executing the following command:\nprint(subset)\n\nshould return:\n[15, 30, 45]\n\nWhat should the blanks be filled with?", + "options": { + "a": "1:len(mylist):3", + "b": "0:len(mylist):3", + "c": "1:len(mylist)-1:3", + "d": "0:len(mylist)-1:3" + }, + "correct": "a", + "explanation": "Starting at index 1 and stepping by 3 gives positions 1, 4, and 7, which are 15, 30, and 45. Using len(mylist) as the stop value includes the last valid stepped element.", + "code_context": "subset = mylist[___:___:___]\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\nprint(subset)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q10", + "number": 10, + "topic": "3_Function_Argument_1", + "question": "Suppose you have the following function:\n\nWhat will be printed by the following line of code?\nprint(main())", + "options": { + "a": "True", + "b": "False", + "c": "0", + "d": "None" + }, + "correct": "d", + "explanation": "The default value of x is 0, so neither if-condition runs and the function reaches the end without returning anything, which prints None.", + "code_context": "def main(x = 0):\n if x > 0:\n return True\n\n if x < 0:\n return False\n\nprint(main())", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q11", + "number": 11, + "topic": "3_Function_Built-in_3", + "question": "Suppose you have a variable called x which contains a list of integers as follows:\nx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nWhich of the following lines will produce an output that is different from the rest?", + "options": { + "a": "print(len(x))", + "b": "print(sorted(x, reverse=True)[0])", + "c": "print(x.index(9))", + "d": "print(sum(x[4:6]))" + }, + "correct": "a", + "explanation": "len(x) is 10, while sorted(x, reverse=True)[0] is 9, x.index(9) is 9, and sum(x[4:6]) is 4 + 5 = 9.", + "code_context": "x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q12", + "number": 12, + "topic": "3_Function_Flexible-Argument_1", + "question": "You want to write a function called main which accepts a flexible number of integers as arguments.\n\nThe function should return a dictionary with the following key-value pairs:\n- key 'sum' has a value which is the sum of all the integers passed as arguments\n- key 'pro' has a value which is the multiplicative product of all the integers passed as arguments\n- key 'pow' has a value which is a list of all the squares of the integers passed as arguments\n\nWhich of the following lines of code will complete the function to give what you need?", + "options": { + "a": "x['sum'] = sum(args)\nx['pro'] = 1\nx['pow'] = []\nfor i in args:\n x['pro'] *= i\n x['pow'].append(i**2)", + "b": "x['sum'] = sum(args)\nx['pro'] = i for i in args\nx['pow'] = [i**2 for i in args]", + "c": "for i in args:\n x['sum'] = sum(args)\n x['pro'] *= i\n x['pow'] = [i**2 for i in args]", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "Option A correctly stores the sum, initializes the product accumulator to 1 before multiplying through the arguments, and builds the list of squares for each integer.", + "code_context": "def main(*args):\n x = {}\n\n # missing lines\n # ...\n\n return x", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option text for question 12, especially options B and C, is small in the rendered page and should be human-confirmed." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q13", + "number": 13, + "topic": "6-string - fstring - 2", + "question": "You have the following objects loaded in Python:\nitem = \"laptop\"\nprice = 1299.99\n\nYou need to print the following sentence:\nThe laptop is priced at $1299.99.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(message)", + "b": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(mesage)", + "c": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)", + "d": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)" + }, + "correct": "a", + "explanation": "Option A correctly uses positional placeholders and prints the defined variable `message`. Option B appears to use a misspelled variable name in the print call, and C/D mix named placeholders with positional arguments.", + "code_context": "item = \"laptop\"\nprice = 1299.99", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option B's printed variable name appears to be `mesage` in the rendered page and should be human-confirmed." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q14", + "number": 14, + "topic": "7-pandas - easy - 1", + "question": "Suppose you have run the following block of code:\n\nimport pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)\n\nWhich of the following lines of code give(s) the following output?\n1 4\n2 5\n3 6\nName: B, dtype: int64", + "options": { + "a": "df.loc[:, 'B']", + "b": "df['B'].loc[:]", + "c": "df['B']", + "d": "All of the given lines." + }, + "correct": "d", + "explanation": "Each of A, B, and C selects the same Series containing column `B`, so the correct choice is that all listed lines produce the shown output.", + "code_context": "import pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q15", + "number": 15, + "topic": "8_Datetime_Easy_1", + "question": "Which code segment gives the same output as the following?\n\ndate = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))\n\nYou may assume that datetime and timedelta classess are already imported from the datetime module.", + "options": { + "a": "print(datetime.strptime('22-05-2023', '%d.%m.%Y'))", + "b": "print('02-05-2023')", + "c": "print(datetime.strptime('05.22.2023', '%d-%m-%Y'))", + "d": "date = datetime.strptime('10/05/2023', '%d/%m/%Y')\nprint((date + timedelta(days=5)).strftime('%m-%d-%Y'))" + }, + "correct": "b", + "explanation": "The original code parses May 12, 2023 and subtracts 10 days, so the printed result is the string `02-05-2023`.", + "code_context": "date = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q16", + "number": 16, + "topic": "9_OOP_Easy_3", + "question": "You have the following definition for a class called Shape:\n\nWhat would be the output if we execute the following commands?\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "options": { + "a": "True", + "b": "False", + "c": "An error", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "`Shape(5, 3).area` is `5 * 3 = 15`, and `Shape(1, 15).length` is `15`, so the comparison evaluates to `True`.", + "code_context": "class Shape:\n def __init__(self, height, length):\n self.height = height\n self.length = length\n self.area = self.height * self.length\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q17", + "number": 17, + "topic": "6-string - operations - 2", + "question": "Write a function called shuffle_sentence that takes a string as an argument and returns a new string where the words are shuffled randomly.\n\nFor example, if your function is called as:\nshuffle_sentence(\"Hello, how are you today?\")\nthen it could return a shuffled string like:\n'how today? you Hello, are'\n\nWhich of the following programs work(s) according to the requirements?\n\nHints:\nThe shuffle() function is a method from the random module. The shuffle() method takes a sequence, like a list, and reorganizes the order of the items. This method changes the original list; it does not return a new list.\nThe reversed() function computes the reverse of a given sequence object and returns it in the form of a list.", + "options": { + "a": "def shuffle_sentence(sentence):\n words = sentence.split()\n return ' '.join(reversed(words))", + "b": "import random\n\ndef shuffle_sentence(sentence):\n words = sentence.split()\n random.shuffle(words)\n return ' '.join(words)", + "c": "Both of the programs work.", + "d": "Neither of the programs work." + }, + "correct": "b", + "explanation": "Option B is the only one that actually shuffles the words randomly. Option A only reverses the word order, which does not satisfy the random-shuffle requirement.", + "code_context": "shuffle_sentence(\"Hello, how are you today?\")\n# could return: 'how today? you Hello, are'", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q18", + "number": 18, + "topic": "6-strings - find & replace - 1", + "question": "Consider the following line of code:\n\ntext = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\n\nYou want to create a new string called new_text where all occurances of \"oil\" are replaced by \"natural gas\".\n\nSo:\nprint(new_text)\nshould return:\n\"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "new_text = ' '.join([word if word != 'oil' else 'natural gas' for word in text.split()])", + "b": "new_text = text.replace(\"oil\", \"natural gas\")", + "c": "new_text = text.split()\nfor index, word in enumerate(new_text):\n if word == 'oil':\n new_text[index] = 'natural gas'\nnew_text = ' '.join(new_text)", + "d": "All of the given options works as intended." + }, + "correct": "d", + "explanation": "All three code fragments replace each occurrence of the standalone word `oil` with `natural gas`, so the correct answer is that all of them achieve the requested result.", + "code_context": "text = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\nprint(new_text)\n# should return:\n# \"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The source image uses the misspelling `occurances`; that spelling was preserved from the rendered page." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q19", + "number": 19, + "topic": "7-pandas - hard - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Select all rows where the age is greater than 30 and the gender is \"Male\".\n- Operation 2: Create a new column called Sex_abbr of which the values should be \"F\" if gender is \"Female\" and \"M\" if gender is \"Male\".\n- Operation 3: Calculate the average salary of all employees.\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df_operation1 = df[(df['Age'] > 30) & (df['Gender'] == 'Male')]\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "b": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "c": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = df['Gender'].map(lambda x: 'M' if x == 'Male' else 'F')\ndf_operation3 = df['Salary'].sum()/len(df)", + "d": "df_operation1 = df[df['Age'] > 30 & df['Gender'] == 'Male']\ndf['Sex_abbr'].map(lambda x: 'M' if x == 'Male' else 'F' for x in df['Gender'])\ndf_operation3 = df['Salary'].sum()/len(df)" + }, + "correct": "a", + "explanation": "Option A correctly filters rows with both conditions using boolean masking, builds the abbreviation column from the Gender column, and computes the average salary with mean().", + "code_context": "Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some punctuation in the non-selected option code snippets is small in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q20", + "number": 20, + "topic": "7-pandas - lambda - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000\n\nYou want to create a new column called Bonus that compute each employee's bonus based on their salary and performance review using the following formula:\n- if the performance review is less than 4, the bonus is 0.\n- if the performance review is 4 or 5, the bonus is 5% of the salary.\n\nWhich of the following code snippets works as intended?", + "options": { + "a": "df['Bonus'] = df.apply(lambda row: row['Salary']*0.05 if row['Performance_review']>=4 else 0, axis=1)", + "b": "df['Bonus'] = df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>=4 else 0)", + "c": "df['Bonus'] = map(df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>4 else 0))", + "d": "df['Bonus'] = df['Salary'].map(lambda row: row*0.05 if df['Performance_review']>=4 else 0)" + }, + "correct": "a", + "explanation": "Option A evaluates each row, checks the row's Performance_review value, and returns either 5% of Salary or 0 for that employee.", + "code_context": "Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q21", + "number": 21, + "topic": "8_Datetime_Function_3", + "question": "You want to create a function called main which take an integer and a flexible number of strings as arguments. The strings represent dates in the format of DD MM YYYY. The day, month and year can be separated by different characters.\n\nYour function should look for the string inputs which represent dates as DD-MM-YYYY or DD/MM/YYYY and return those strings in the format of DD.MM.YYYY in a list. Furthermore, the dates represented by the strings should be shifted by the amount of days as given by the integer argument.\n\nFor example, if we call your function as:\nmain(3, '25/06/2003', '26.06.2003', '27-06-2003', '28:06:2023', '29-06-2023', '30.06.2023')\n\nthe output should be:\n['28.06.2003', '30.06.2003', '02.07.2023']\n\nTake a look at the following code segment. Does it do what is intended? If not, then why not?", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the function will return a list of datetime objects, not a list of strings representing dates.", + "c": "This code segment does not work because the strftime() method cannot be applied to NoneType object.", + "d": "This code segment produces an error because you cannot concatenate strings and timedelta." + }, + "correct": "b", + "explanation": "The function parses matching inputs and adds the day offset, but it appends datetime objects and never converts them back to strings in DD.MM.YYYY format before returning.", + "code_context": "def main(delta, *args):\n dates = []\n for string in args:\n if '-' in string:\n dates.append(datetime.strptime(string, '%d-%m-%Y') + timedelta(days=delta))\n elif '/' in string:\n dates.append(datetime.strptime(string, '%d/%m/%Y') + timedelta(days=delta))\n else:\n dates.append(None)\n return [date for date in dates if type(date) != None]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q22", + "number": 22, + "topic": "8_Datetime_Hard_2", + "question": "You want to define a class called Calendar, which has four attributes that are initialized at the time of object construction:\n1. The 'event' attribute can be any string,\n2. The 'date' attribute is a string representing a date as 'DD-MM-YYYY',\n3. The 'start' attribute is a string representing the time as 'HH:MM', and\n4. The 'length' attribute is an integer representing the amount of minutes.\n\nThe class should also have a method called get_details() that gives a description of Calendar objects.\n\nFor example, if we execute the following commands;\nevent1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n\nthe output should be:\nCoffee meeting: 01-06-2023, 9:30-9:50.\n\nWhich of the following code segments gives you what you want?", + "options": { + "a": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day, int(start.split(':')[0]), int(start.split(':')[1]))\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "b": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.split(':')[0], minute=start.split(':')[1])\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "c": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.hour, minute=start.minute)\n self.end = self.self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "d": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start.hour = start.hour\n self.start.minute = start.minute\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'" + }, + "correct": "a", + "explanation": "Option A is the only choice that correctly parses the date string, combines the parsed date with the split start time to build a datetime, adds the duration in minutes, and formats the requested details string.", + "code_context": "event1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n# output:\n# Coffee meeting: 01-06-2023, 9:30-9:50.", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q22-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some small format-code and punctuation characters in the non-selected option snippets are hard to read in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q23", + "number": 23, + "topic": "9_OOP_Function_2", + "question": "You have the following definition for a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nYou want to add three methods to this class:\n1. The holiday_bonus() method which computes and returns the holiday bonus, which is 8.0% of the yearly salary,\n2. The year_end_bonus() method which computes and returns the year end bonus, which is 8.3% of the yearly salary\n3. The payment_overview() method which returns a payment overview of the employee using the following format:\n[Name] receives $[salary] monthly, $[holiday bonus] in May and $[year end bonus] in December.\n\nFor example, if we execute the following commands:\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())\n\nthe output should be:\n2400.0\n2490.0\nJohn Smith receives $2500 monthly, $2400.0 in May and $2490.0 in December.\n\nWhich of the following code segments should you place on the blank in the class definition to achieve what you want?", + "options": { + "a": "def holiday_bonus(self):\n return self.salary * 12 * 0.080\ndef year_end_bonus(self):\n return self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus()} in May and ${self.year_end_bonus()} in December.'", + "b": "def payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.salary*12*0.08} in May and ${self.salary*12*0.083} in December.'", + "c": "def holiday_bonus():\n self.holiday_bonus = self.salary * 12 * 0.080\ndef year_end_bonus():\n self.year_end_bonus = self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'", + "d": "def payment_overview(self):\n self.holiday_bonus = self.salary * 12 * 0.080\n self.year_end_bonus = self.salary * 12 * 0.083\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'" + }, + "correct": "a", + "explanation": "Option A defines all three requested methods, computes the two bonuses from the yearly salary, and uses those method results in the overview string.", + "code_context": "class Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q22-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q24", + "number": 24, + "topic": "9_OOP_Hard_2", + "question": "You have the following definitions for a class called Car:\n\nclass Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nYou want to create another class called Garage, which has two attributes that are initialized during object construction:\n- The 'capacity' attribute, which is an integer and must be passed to the object constructor.\n- The 'cars' attribute, which is an empty list.\n\nThe Garage class should also have two methods:\n1. The add_car() method, which adds Car objects to a Garage object. New Car objects can only be added if there is still capacity in the Garage object. If not, the method should return \"Capacity reached.\"\n2. The check_garage() method, which reports the Car objects that have been added to the Garage object. The method should return a dictionary in which the keys are the counts of Car objects starting from 1 and the values are the Car objects' descriptions.\n\nFor example, if we execute the following commands:\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n\nthe output should be:\n{1: 'Toyota, Camry', 2: 'Honda, Accord'}\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "class Garage:\n def __init__(self, capacity, cars = []):\n self.capacity = capacity\n\n def add_car(self, car):\n self.cars += car if len(self.cars) < self.capacity else return 'Capacity reached.'\n\n def check_garage(self, car):\n return {index: car.get_description() for index, car in enumerate(self.cars, start=1)}", + "b": "class Garage:\n def __init__(self, capacity):\n self.capacity = capacity\n self.cars = []\n\n def add_car(self, car):\n if len(self.cars) < self.capacity:\n self.cars.append(car)\n else:\n return 'Capacity reached.'\n\n def check_garage(self):\n output = {}\n for index, car in enumerate(self.cars, start=1):\n output[index] = car.get_description()\n return output", + "c": "Both of the above will work.", + "d": "None of the above will work." + }, + "correct": "b", + "explanation": "Option B initializes capacity and an empty cars list, appends cars only when capacity remains, returns the required message when full, and builds the requested dictionary in check_garage().", + "code_context": "class Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n# output:\n# {1: 'Toyota, Camry', 2: 'Honda, Accord'}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q22-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some punctuation in non-selected option A is small in the rendered PNG and should be human-confirmed." + ] + } + } + ], + "blocked_questions": [] + }, + { + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "title": "2024 Trial Final", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/introduction-to-python-trial-final-exam-solutions-py22.pdf", + "expected_questions": 24, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-01.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-02.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-03.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-04.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-06.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-07.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-08.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-09.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-10.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-11.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-12.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-13.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-14.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-15.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-16.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-17.png" + ], + "page_count": 17, + "duplicate_aliases": [], + "seed_sources": { + "legacy_assessment_payload_path": "data/import_payloads/post_midterm_assessments/introduction-to-python-trial-final-exam-solutions-py22.json", + "study_db_exam_label": "trial-final-exam-py22", + "study_db_exam_source": "materials/post_midterm/practice_exams_previous_years/introduction-to-python-trial-final-exam-solutions-py22.pdf", + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review." + }, + "review_tracking": { + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "legacy_seeded_questions": 0, + "pending_vision_questions": 0 + }, + "extraction_status": "partial", + "questions": [ + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q01", + "number": 1, + "topic": "1_Basics_Logic_3", + "question": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?", + "options": { + "a": "if x in list(range(11))[::2]:\n print('Even number')\nelse:\n print('Odd number')", + "b": "if x % 2 != 0:\n print('Odd number')\nelse:\n print('Even number')", + "c": "if x in [1, 3, 5, 7, 9]:\n print('Odd number')\nelse:\n print('Even number')", + "d": "All of the programs work as intended." + }, + "correct": "d", + "explanation": "Option A checks membership in the even numbers from 0 through 10, option B checks oddness with modulo, and option C checks membership in the odd numbers from 1 through 9. All three correctly classify x as odd or even in the stated range.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-02.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q02", + "number": 2, + "topic": "1_Basics_Scope_2", + "question": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "options": { + "a": "This code will produce an error because a is a global name that is referenced inside the local scope of inner().", + "b": "This code will not produce any error and will return 30.", + "c": "This code will produce an error because c is not defined before referencing.", + "d": "This code will not produce any error and will return 50." + }, + "correct": "b", + "explanation": "The function inner receives c as its argument, so c is defined. It can also read the global a. inner(5) returns 1 + 5 + 4 = 10, and outer returns 10 * 3 = 30.", + "code_context": "a = 1\ndef outer(b):\n b = 3\n def inner(c):\n d = 4\n return a + c + d\n return inner(5) * b\nouter(5)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-02.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q03", + "number": 3, + "topic": "1_Basics_Variables_2", + "question": "What will be returned by the following code segment?", + "options": { + "a": "[0, None, 2, 3, None, 5, 6, 7, 8, None]", + "b": "[0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, 9]", + "c": "[None, 1.0, None, None, 3.5, None, None, None, None, '9']", + "d": "[0, None, 2, 3, None, 5, 6, 7, 8, 9]" + }, + "correct": "a", + "explanation": "The function appends each item if its exact type is int; otherwise it appends None. In the given list, 1.0, 3.50, and '9' are not ints, so those positions become None.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n if type(item) == int:\n list_2.append(item)\n else:\n list_2.append(None)\n return list_2\n\nmain([0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, '9'])", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-03.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q04", + "number": 4, + "topic": "2-dictionaries - comprehension - 2", + "question": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}", + "b": "roman_nums = {roman: num for roman, num in zip(['I', 'II', 'III', 'IV', 'V'], range(1, 6))}", + "c": "roman_nums = {num: ['I', 'II', 'III', 'IV', 'V'][num] for num in range(1, 6)}", + "d": "roman_nums = {num: roman for num, roman in zip(range(1, 6), 'I II III IV V')}" + }, + "correct": "a", + "explanation": "Option A zips the integers 1 through 5 with the five Roman numeral strings and builds the required dictionary. The other options either reverse the keys and values, use incorrect indexing, or iterate over a plain string instead of the intended list of numerals.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-03.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q05", + "number": 5, + "topic": "2-dictionaries - manipulation - 2", + "question": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to only include the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[name] = age", + "b": "person_dict = {}\nfor i, name in enumerate(names):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[i] = ages[i]", + "c": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict.append(name:age)", + "d": "person_dict = {}\nfor i, name in enumerate(names):\n for j, letter in enumerate(name):\n if letter == 'A' or letter == 'C':\n person_dict[i] = ages[j]" + }, + "correct": "a", + "explanation": "Option A correctly iterates over names and ages together and stores only the names beginning with A or C as keys mapped to their ages. The other options use indices as keys, invalid dictionary syntax, or incorrect nested-loop logic.", + "code_context": "names = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q06", + "number": 6, + "topic": "2-dictionaries - slicing - 2", + "question": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?", + "options": { + "a": "max_rating = max(employee_ratings.values())\nfor employee, rating in employee_ratings.items():\n if rating == max_rating:\n print(employee)", + "b": "max_rating_employee = max(employee_ratings.keys())\nfor employee, rating in employee_ratings.items():\n if employee == max_rating_employee:\n print(employee)", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "a", + "explanation": "Option A correctly computes the maximum rating value and prints every employee whose rating matches it. Option B instead finds the maximum key lexicographically, not the employee with the highest rating.", + "code_context": "employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q07", + "number": 7, + "topic": "2-list - comprehension - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[2, 4]", + "b": "[3, 4, 5]", + "c": "[4]", + "d": "[]" + }, + "correct": "c", + "explanation": "The list comprehension keeps values x from [1, 2, 3, 4, 5] only when x is even and greater than 2. The only value satisfying both conditions is 4.", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x for x in numbers if x % 2 == 0 and x > 2]\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q08", + "number": 8, + "topic": "2-list - manipulation - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "['a', 'bb', 'ccc']", + "b": "[1, 2, 3]", + "c": "[1, 'b', 3]", + "d": "['aa', 'bb', 'cc']" + }, + "correct": "a", + "explanation": "The loop iterates over pairs from zip(list1, list2) and multiplies each string by its matching integer, producing 'a', 'bb', and 'ccc'.", + "code_context": "list1 = [1, 2, 3]\nlist2 = ['a', 'b', 'c']\nresult = []\nfor item in zip(list1, list2):\n result.append(item[0] * item[1])\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q09", + "number": 9, + "topic": "2-list - slicing - 1", + "question": "Suppose you have a list called mylist. You want to extract every fourth element starting from index 2 (inclusive) to the second-to-last index (inclusive) of that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45, 50]\n\nthen executing the following command:\nprint(subset)\n\nshould print:\n[20, 35]\n\nWhat should the blanks be filled with?", + "options": { + "a": "2:-1:3", + "b": "2:len(mylist)-1:3", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "c", + "explanation": "Both stop values exclude the last element while starting at index 2 and stepping by 3, so both expressions return [20, 35] for the example list.", + "code_context": "subset = mylist[___:___:___]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q10", + "number": 10, + "topic": "3_Function_Argument_2", + "question": "Suppose you have the following function, which takes a list of integers as an argument:\n\nWhat will be returned, if we call the function as follows:\nmain([0, 1, 2, 23, 24, 25])", + "options": { + "a": "'abcxyz'", + "b": "['a', 'b', 'c', 'x', 'y', 'z']", + "c": "'012232425'", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "The function walks through the alphabet with enumerate and appends each character whose index is present in the input list, giving a, b, c, x, y, and z.", + "code_context": "def main(x):\n alphabet = 'abcdefghijklmnopqrstuvwxyz'\n y = ''\n for index, character in enumerate(alphabet):\n if index in x:\n y += character\n return y", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q11", + "number": 11, + "topic": "3_Function_Built-in_1", + "question": "Suppose you have a variable called x which contains a string as follows:\n\nx = 'Hello world'\n\nWhich of the following lines of code produce(s) 2 as an output?", + "options": { + "a": "print(x.count('o'))", + "b": "print(x.split(' ')[0].count('ll'))", + "c": "print(len(x)//5)", + "d": "All of the given options." + }, + "correct": "d", + "explanation": "The rendered solution page marks option D, indicating that the exam intends all three listed expressions to produce 2 for the given value of x.", + "code_context": "x = 'Hello world'", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page.", + "Option B's inner string literal is small in the source image and should be human-confirmed during merge review." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q12", + "number": 12, + "topic": "3_Function_Flexible-Argument_2", + "question": "You need to write a function called main which accepts a list of integers as an argument. The function should return a tuple of two integers, in which the first is the sum of the squares of all even numbers, and the second is the sum of the squares of all odd numbers.\n\nFor example, calling the function as:\nmain(1, 2, 3, 4)\nshould return:\n(20, 10)\n\nWhich of the following blocks of code fits with the rest of the program and will you give the intended output?", + "options": { + "a": "for i in args:\n if i % 2 == 0:\n total_even += i**2\n else:\n total_odd += i**2\n\nreturn (total_even, total_odd)", + "b": "for i in args:\n if i % 2 == 1:\n total_even += i\n else:\n total_odd += i\n\nreturn (total_even**2, total_odd**2)", + "c": "for i in args:\n if i % 2 == 0:\n total_even.append(i**2)\n else:\n total_odd.append(i**2)\n\nreturn (sum(total_even), sum(total_odd))", + "d": "All of the given code blocks work as intended." + }, + "correct": "a", + "explanation": "Option A directly accumulates the squares of even numbers and odd numbers into the two totals and returns them as the required tuple.", + "code_context": "def main(*args):\n total_even = 0\n total_odd = 0\n\n # missing lines\n # ...", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q13", + "number": 13, + "topic": "6-string - fstring - 1", + "question": "You have the following objects loaded in Python:\nname = \"Alice\"\nage = 25\ncountry = \"the USA\"\n\nYou need to print the following string:\nMy name is Alice. I am 25 years old, and I am from the USA.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"My name is {0}. I am {2} years old, and I am from {1}.\".format(name, country, age)\nprint(message)", + "b": "message = f\"My name is {name}. I am {age} years old, and I am from {country}.\"\nprint(message)", + "c": "message = 'My name is ' + name + '. I am ' + str(age) + ' years old, and I am from ' + str(country) + '.'\nprint(message)", + "d": "All of the given options are correct." + }, + "correct": "d", + "explanation": "All three code variants produce the target sentence: one uses format, one uses an f-string, and one uses string concatenation with str(age) and str(country).", + "code_context": "name = \"Alice\"\nage = 25\ncountry = \"the USA\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q14", + "number": 14, + "topic": "7-pandas - easy - 2", + "question": "Suppose you have the following DataFrame called df, and assume that pandas is already imported:\n\n Player Goals Assists\n0 John 5 2\n1 Jane 3 6\n2 Alex 2 4\n\nAll of the following lines of code make the same selection, but one of the results has a different datatype. Which one?", + "options": { + "a": "df.loc[:, 'Goals']", + "b": "df['Goals']", + "c": "df.loc[[0, 1, 2], 'Goals']", + "d": "df.loc[:, ['Goals']]" + }, + "correct": "d", + "explanation": "The first three expressions return a Series, while selecting with a list of column names returns a one-column DataFrame instead.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q15", + "number": 15, + "topic": "8_Datetime_Easy_3", + "question": "Which code segment gives the same output as the following:\n\ndate1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module.", + "options": { + "a": "print((datetime(2023, 5, 1) - datetime(2023, 6, 1)).days)", + "b": "print((datetime(2023, 6, 1) - datetime(2023, 1, 5)).days)", + "c": "print((datetime.strptime('2023-6-1', '%Y-%d-%m') - datetime.strptime('2023-5-1', '%Y-%d-%m')).days)", + "d": "print((datetime.strptime('2023-06-01', '%Y-%m-%d') - datetime.strptime('2023-05-01', '%Y-%m-%d')).days)" + }, + "correct": "d", + "explanation": "Option D parses ISO-style date strings using the matching '%Y-%m-%d' format and subtracts the May date from the June date, giving the same day difference as the original code.", + "code_context": "date1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q16", + "number": 16, + "topic": "9_OOP_Easy_2", + "question": "You have the following definition of a class called Flight. What would be the output if we execute the following statements?", + "options": { + "a": "'long'\n'cheap'", + "b": "'short'\n'expensive'", + "c": "'long'\n'expensive'", + "d": "'short'\n'cheap'" + }, + "correct": "a", + "explanation": "The first condition sets the KLM flight to Singapore to duration 'long', and the second condition sets the EasyJet flight to Spain to price 'cheap', so the two prints output 'long' and then 'cheap'.", + "code_context": "class Flight:\n def __init__(self, airline, destination):\n self.airline = airline\n self.destination = destination\n\n if self.airline == 'KLM' and self.destination == 'Singapore':\n self.duration = 'long'\n self.price = 'expensive'\n\n if self.airline == 'EasyJet' and self.destination == 'Spain':\n self.duration = 'short'\n self.price = 'cheap'\n\nprint(Flight('KLM', 'Singapore').duration)\nprint(Flight('EasyJet', 'Spain').price)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q17", + "number": 17, + "topic": "6-string - operations - 1", + "question": "Consider the following code snippet. Which operation in the code snippet contains an error?", + "options": { + "a": "Operation 1", + "b": "Operation 2", + "c": "Operation 3", + "d": "None of the operations contains an error." + }, + "correct": "b", + "explanation": "Operation 2 is incorrect because join should be called as the separator string's method with a single iterable argument, for example '-'.join(word_list).", + "code_context": "text = \"The universe is vast and full of mysteries!\"\n\n# Operation 1:\nword_list = []\nfor word in text.split():\n word_list.append(word[::-1])\n\n# Operation 2:\njoined_text = ' '.join(word_list, '-')\n\n# Operation 3:\nreplaced_text = text.replace(\"mysteries\", \"secrets\")", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q18", + "number": 18, + "topic": "6-strings - find - 2", + "question": "Suppose you have the following variables called sentence1 and sentence2 which contain strings. The sentences contain names, but they are not properly capitalized. You want to create a new string object called paragraph, with the proper nouns capitalized in the two sentences and the two sentences connected into one big string.\n\nThat is, if we execute the following line of code:\nprint(paragraph)\nthe output should be:\n\"Harry, Ron, and Hermione walked through the halls of Hogwarts; their footsteps echoing off the stone walls.\nThe Marauder's map in Harry's hands revealed the secret passageways and hidden rooms of the castle.\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor name in names:\n sentence1[sentence1.find(name)] = name.capitalize()\n sentence2[sentence2.find(name)] = name.capitalize()\nparagraph = sentence1 + \" \" + sentence2", + "b": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor word, name in zip(sentence1, names):\n if word == name:\n sentence1 = sentence1.replace(word, name.capitalize())\nfor word, name in zip(sentence2, names):\n if word == name:\n sentence2 = sentence2.replace(word, name.capitalize())\nparagraph = sentence1 + \" \" + sentence2", + "c": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nnew1 = ' '.join([word.capitalize() if word in names else word for word in sentence1])\nnew2 = ' '.join([word.capitalize() if word in names else word for word in sentence2])\nparagraph = new1 + \" \" + new2", + "d": "for word in ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']:\n sentence1 = sentence1.replace(word, word.capitalize())\n sentence2 = sentence2.replace(word, word.capitalize())\nparagraph = sentence1 + \" \" + sentence2" + }, + "correct": "d", + "explanation": "Option D correctly replaces each lowercase proper noun with its capitalized version in both strings and then concatenates the two sentences into paragraph.", + "code_context": "sentence1 = \"harry, ron, and hermione walked through the halls of hogwarts; their footsteps echoing off the stone walls.\"\nsentence2 = \"The marauder's map in harry's hands revealed the secret passageways and hidden rooms of the castle.\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q19", + "number": 19, + "topic": "7-pandas - hard - 2", + "question": "Consider the following pandas DataFrame called df, and assume that Pandas is already imported.\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Name_Length that contains the length of each person's name\n- Operation 2: Replace all occurrences of the occupation 'Engineer' with 'Software Developer'\n- Operation 3: Extract the last two characters of each person's name and store them in a new column called Name_Suffix\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df['Name_Length'] = df['Name'].map(lambda x: len(x))\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:])", + "b": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].lambda x: x[-2:]", + "c": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[:-2])", + "d": "df['Name_Length'] = df['Name'].map(len)\ndf['Occupation'] = df['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:-1])" + }, + "correct": "a", + "explanation": "Option A correctly maps each name to its length, replaces only the Engineer entries, and slices the final two characters with x[-2:].", + "code_context": "Name Age Occupation\n0 John 25 Student\n1 Jane 30 Engineer\n2 Alex 35 Scientist\n3 Lisa 40 Doctor\n4 Mark 28 Architect", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q20", + "number": 20, + "topic": "7-pandas - lambda - 2", + "question": "What will be printed by the following code?", + "options": { + "a": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 72 13\n1 B 45 19", + "b": "Product Units Price\n1 B 50 19\n0 A 100 10\n3 D 80 13\n2 C 200 15", + "c": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 80 13\n1 B 50 19", + "d": "Product Units Price\n2 C 200 15\n3 D 80 13\n0 A 100 10\n1 B 50 19" + }, + "correct": "c", + "explanation": "UnitsCorrected and Revenue are used only for sorting; df1 keeps the original Units and Price columns, and sorting by descending revenue gives rows C, A, D, B.", + "code_context": "import pandas as pd\nd = {'Product':['A', 'B', 'C', 'D'], 'Units':[100, 50, 200, 80], 'Price':[10, 19, 15, 13]}\ndf = pd.DataFrame(d)\ndf.loc[:, 'UnitsCorrected'] = df.loc[:, 'Units'].map(lambda x: 0.9*x if x < 100 else x)\ndf.loc[:, 'Revenue'] = df.loc[:, 'UnitsCorrected'] * df.loc[:, 'Price']\ndf = df.sort_values(by='Revenue', ascending=False)\ndf1 = df.loc[:, ['Product', 'Units', 'Price']]\nprint(df1)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q21", + "number": 21, + "topic": "8_Datetime_Function_2", + "question": "You have the following definition for a class called Calendar.\n\nThe method check_overlap() should return True if there are two overlapping events and False if the two events are not overlapping.\n\nFor example, if we have the following Calendar objects:\nevent1 = Calendar('Coffee meeting', '01-06-2023 9:30', 20)\nevent2 = Calendar('Writing session', '01-06-2023 10:00', 150)\nevent3 = Calendar('Lunch meeting', '01-06-2023 12:00', 45)\n\nthe following command should return False:\nprint(event1.check_overlap(event2))\n\nand the following command returns True:\nprint(event2.check_overlap(event3))\n\nDoes the code segment given above do what you want? If not, then why not?\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the condition provided after the return keyword is incorrect.", + "c": "This code segment does not work because the syntax to parse the input string to create a datetime object is incorrect.", + "d": "This code segment does not work because the __init__ method needs 4 parameters and only 3 arguments are passed." + }, + "correct": "a", + "explanation": "The datetime format string matches the input values, timedelta(minutes=length) creates the correct end time, and the overlap condition correctly detects whether two intervals intersect.", + "code_context": "from datetime import datetime, timedelta\n\nclass Calendar():\n def __init__(self, event, start, length):\n self.event = event\n self.start = datetime.strptime(start, '%d-%m-%Y %H:%M')\n self.end = self.start + timedelta(minutes=length)\n def check_overlap(self, other):\n return self.start < other.end and self.end > other.start", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q22", + "number": 22, + "topic": "8_Datetime_Hard_1", + "question": "You want to create a DataFrame called df that has the following format:\n\n Day Month Year\n01-01-23 1 1 2023\n08-01-23 8 1 2023\n15-01-23 15 1 2023\n22-01-23 22 1 2023\n29-01-23 29 1 2023\n\nWhich of the following code segments achieves what you want?\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module, as well as the pandas module (via: import pandas as pd).\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "dates = [(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=[date.strftime('%d-%m-%y') for date in dates])", + "b": "dates = [(datetime(2023, 1, 1) + timedelta(days=7*i)).strftime('%d-%m-%y') for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=dates)", + "c": "day = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).day for i in range(5)])\nmonth = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).month for i in range(5)])\nyear = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).year for i in range(5)])\ndf = pd.DataFrame(data=[day, month, year])", + "d": "df = pd.DataFrame(index=[(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)],\n {'Day': [date.days for date in index],\n 'Month': [date.months for date in index],\n 'Year': [date.year for date in index]})" + }, + "correct": "a", + "explanation": "Option A keeps real datetime objects long enough to derive day, month, year, and then formats those dates into the desired string index for the DataFrame.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q23", + "number": 23, + "topic": "9_OOP_Function_3", + "question": "You have the following definition of a class called Pack.\n\nYou want to add to this class a method called fitting() that calculates how many times another object of the class Pack would fit inside this object.\nThe method should return the number of times these other objects would fit completely in this object, and the final value.\nThe final value is the sum of all values of all objects that fit in it, plus the value of the carrying object self.\n\nFor example, if we execute the lines of code:\nbackpack = Pack(size=15, value=20)\nbook = Pack(size=4, value=10)\nbackpack.fitting(book)\n\nthe output should be:\nAmount: 3. Value: 50.\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def fitting(self, other):\n if self.size > other.size:\n self.total = (self.size // other.size) * other.value + self.value\n return f'Amount: {self.size // other.size}. Value: {self.total}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "b": "def fitting(self, other):\n if self.size > other.size:\n return f'Amount: {self.size // other.size}. Value: {other.value * other.size}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "c": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return f'Amount: {self.amount}. Value: {self.total}.'", + "d": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return 'Amount: {}. Value: {}.'.format(self.amount, self.value if self.size > other.size else self.total)" + }, + "correct": "a", + "explanation": "Option A uses integer floor division to count only full fits, adds the carried items' value plus self.value, and returns zero items with self.value when the other object does not fit.", + "code_context": "class Pack:\n def __init__(self, size, value = 0):\n self.size = size\n self.value = value\n\n # missing lines\n # ...", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q24", + "number": 24, + "topic": "9_OOP_Hard_1", + "question": "You have the following definition for a class called Piece.\n\nAnd the creation of three objects with the help of the class definition:\na = Piece(diagonal=True, straight=False, initial_position=(0, 0))\nb = Piece(diagonal=False, straight=True, initial_position=(4, 3))\nc = Piece(diagonal=True, straight=True, initial_position=(9, 6))\n\nIf we run the following statements:\nprint(a.check_move((4, 4)))\nprint(b.check_move((5, 5)))\nprint(c.check_move((6, 6)))\n\nThis will print 3 Boolean values. Of these values, how many times will this be True?", + "options": { + "a": "0", + "b": "1", + "c": "2", + "d": "3" + }, + "correct": "b", + "explanation": "The first move fails because the row and column differences are both 4, which is above the allowed maximum of 3. The second fails because a straight-only piece cannot move diagonally. The third succeeds because a piece that can move straight and diagonally may move along the same column within 3 steps, so exactly one result is True.", + "code_context": "class Piece:\n def __init__(self, diagonal, straight, initial_position):\n self.diagonal = diagonal\n self.straight = straight\n self.initial_position = initial_position\n\n def check_move(self, target_position):\n self.target_position = target_position\n self.row_diff = self.target_position[0] - self.initial_position[0]\n if abs(self.row_diff) > 3:\n return False\n self.col_diff = self.target_position[1] - self.initial_position[1]\n if abs(self.col_diff) > 3:\n return False\n\n if self.diagonal and (not self.straight):\n return abs(self.row_diff) == abs(self.col_diff)\n if self.straight and (not self.diagonal):\n return abs(self.row_diff) == 0 or abs(self.col_diff) == 0\n if self.straight and self.diagonal:\n return (abs(self.row_diff) == abs(self.col_diff)) or (abs(self.row_diff) == 0 or abs(self.col_diff) == 0)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-17.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ], + "blocked_questions": [] + }, + { + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "title": "2023 Resit Exam Guidelines", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.pdf", + "expected_questions": 24, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-01.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-02.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-07.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-08.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-09.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-10.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-11.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-12.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-13.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-14.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-15.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-16.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-17.png" + ], + "page_count": 17, + "duplicate_aliases": [], + "seed_sources": { + "legacy_assessment_payload_path": "data/import_payloads/post_midterm_assessments/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json", + "study_db_exam_label": "Test Resit - Introduction to Python - 22/23", + "study_db_exam_source": "materials/post_midterm/practice_exams_previous_years/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.pdf", + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review." + }, + "review_tracking": { + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "legacy_seeded_questions": 0, + "pending_vision_questions": 0 + }, + "extraction_status": "partial", + "questions": [ + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01", + "number": 1, + "topic": "Multiple choice - Question-ID: 357615", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "All three expressions evaluate to True: 2 * 3 = 6 equals x[2][1], 3 + 5 = 8 equals x[-1][1], and 7 - 5 = 2 equals x[0][1].", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q02", + "number": 2, + "topic": "Multiple choice - Question-ID: 357607", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "The function called power should not return the string 'The result of {} ** {} is: {}'.format(num, factor, result), but the value of result.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "Result is a local name that cannot be referenced outside of the function power." + }, + "correct": "d", + "explanation": "`result` is defined inside the function `power`, so it is local to that function. The statement `print(result)` outside the function therefore raises a name error because `result` is not defined there.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}'.format(num, factor, result)\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03", + "number": 3, + "topic": "Multiple choice - Question-ID: 355235", + "question": "What will be printed by the following code segment?", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[]", + "d": "[None]" + }, + "correct": "d", + "explanation": "The code appends list-typed elements to `y`, but the return expression uses `append`, which itself returns `None`. The page marks option D as correct, so the intended evaluated output is `[None]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n\n return [y.append(i)]\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Question 3 return line is small in the rendered PNG and should be human-confirmed during merge review." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04", + "number": 4, + "topic": "function defaults and loops", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "This code produces an error as there is a missing argument when calling main.", + "b": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10']", + "c": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')", + "d": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10',\n '1 * 11 = 11']" + }, + "correct": "b", + "explanation": "`main(1)` is valid because `y` has default value `11`. The loop starts at `i = 1` and runs while `i < y`, so it appends the multiplication strings for 1 through 10 and stops before 11.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nprint(main(1))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05", + "number": 5, + "topic": "list slicing and sets", + "question": "Suppose you have a list called x, where:\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Option A removes duplicates and sorts descending, which gives `[5, 4, 3, 2, 1]`. Option B takes every second element from the end of the symmetric list and also prints `[5, 4, 3, 2, 1]`.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n# target output:\n# [5, 4, 3, 2, 1]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06", + "number": 6, + "topic": "keyword arguments", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "To sum the numeric keyword-argument values, the function must iterate over `kwargs.values()`. Option A adds the string keys instead of the prices, and Option C incorrectly tries to unpack `kwargs.keys()`.", + "code_context": "main(apple=1.99, banana=0.99, orange=1.49)\n# should return 4.47", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "number": 7, + "topic": "Dictionaries and Mappings", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {word: len for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to the length of that word. The other options either reverse key/value order or use invalid logic.", + "code_context": "", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "number": 8, + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades.\n\nThe students list contains strings representing the names of students.\nThe grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears. B builds lists of students per grade instead of counting them.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "number": 9, + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the right result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "number": 10, + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "number": 11, + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "number": 12, + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "number": 13, + "topic": "Multiple choice", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", leaving only the second occurrence replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "number": 14, + "topic": "Multiple choice", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the requested sentence exactly, including the word \"and\" before the final fruit. Option A joins the list as \"apple, banana, orange\" and does not produce the exact requested wording.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "number": 15, + "topic": "Multiple choice", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})", + "b": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "c": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "d": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)" + }, + "correct": "d", + "explanation": "Option D constructs one aligned series for the local parts and one for the domains, then returns them in a DataFrame with the correct column names. The other options either overwrite values, build the wrong structure, or use the wrong field names.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "number": 16, + "topic": "Multiple choice", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "False\nTrue", + "c": "False\nFalse", + "d": "True\nFalse" + }, + "correct": "a", + "explanation": "The object is created with name 'John Smith', and because no gender argument is passed, the default value 'not specified' is used. Both comparisons therefore evaluate to True.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "number": 17, + "topic": "Multiple choice", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original expression computes the number of days between January 10 and January 1, then adds 1, which yields 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option B contains a small formatting detail that should be human-confirmed from the page, but the marked correct answer is clearly D." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "number": 18, + "topic": "Multiple choice", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df[['Player', 'Age']])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df.loc[:, 'Age'])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing in this form does not accept the tuple (1, 'Age') to select a single cell.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "number": 19, + "topic": "animals methods", + "question": "You have the following definition for a class called Animals:\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs = True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin = True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "def walk():\n return sound if legs else 'Cannot walk!'\ndef swim():\n return sound if fin else 'Cannot swim!'", + "d": "def walk():\n if legs == True:\n return sound\n else:\n return 'Cannot walk!'\ndef swim():\n if fin == True:\n return sound\n else:\n return 'Cannot swim!'" + }, + "correct": "a", + "explanation": "Option A is the only choice that defines both instance methods with self and correctly returns self.sound when the corresponding boolean attribute is truthy, otherwise the required fallback string.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ...", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-11.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Question stem is on page-11.png and answer options continue on page-12.png." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "number": 20, + "topic": "movie review methods", + "question": "You have the following definition for a class named Movie.\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute,\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and return the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segments will work as intended." + }, + "correct": "d", + "explanation": "Option A is broken because add_review uses list-plus-number syntax and compare immediately returns on the first loop iteration, so it never returns other.title when the other movie has the higher rating. Option B is also broken because add_review and rating are missing self and compare compares method objects instead of calling them.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ...", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "number": 21, + "topic": "datetime weekly dates list", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "b": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "c": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "d": "This code segment will work as intended." + }, + "correct": "c", + "explanation": "After the first append, the newly added element is a formatted string, so on the next loop iteration the code tries to add a timedelta to a string instead of to a datetime object.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "number": 22, + "topic": "pandas date column from day month year", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A correctly constructs datetime objects in year-month-day order from the three columns and then formats them into the requested DD-MM-YYYY strings.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "number": 23, + "topic": "pandas above average salary", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 1000\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "None of the blocks of code will work as intended.", + "c": "Both blocks of code will work as intended.", + "d": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])" + }, + "correct": "a", + "explanation": "Option A correctly computes the mean salary, builds both required columns, and prints the full DataFrame filtered to rows where Above_average is True. Option D does not print the result in the required way because it filters only on Salary_difference > 0 rather than explicitly using the Above_average column requested in the specification.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The printed output in option D would likely show the same rows, but option A more directly matches the stated required operations and final result." + ] + } + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "number": 24, + "topic": "pandas lambda output", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "b": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "c": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15", + "d": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18" + }, + "correct": "d", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing C values 16, 17, and 18.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-17.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ], + "blocked_questions": [] + }, + { + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "title": "2023 Resit Solutions", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/resit-solutions-for-introduction-to-python-35761538.pdf", + "expected_questions": 24, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-01.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-02.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-03.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-04.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-06.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-07.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-08.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-09.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-10.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-11.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-12.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-13.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-14.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-15.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-16.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-17.png" + ], + "page_count": 17, + "duplicate_aliases": [], + "seed_sources": { + "legacy_assessment_payload_path": "data/import_payloads/post_midterm_assessments/resit-solutions-for-introduction-to-python-35761538.json", + "study_db_exam_label": "Resit 22/23", + "study_db_exam_source": "materials/post_midterm/practice_exams_previous_years/resit-solutions-for-introduction-to-python-35761538.pdf", + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review." + }, + "review_tracking": { + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "legacy_seeded_questions": 0, + "pending_vision_questions": 0 + }, + "extraction_status": "partial", + "questions": [ + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q01", + "number": 1, + "topic": "1_Basics_Logic_1", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "The three code lines evaluate to 2 * 3 == 6, 3 + 5 == 8, and 7 - 5 == 2, so each one is True. Therefore the correct choice is that all lines print True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The left option labels are partially obscured by the rendered page overlay, but the visible option texts and the selected outcome verify the answer." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q02", + "number": 2, + "topic": "1_Basics_Scope_1", + "question": "Executing the following program will produce an error. Why?\n\ndef power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)", + "options": { + "a": "Result is a local name that cannot be referenced outside of the function power.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "The function called power should not return the string 'The result of {} ** {} is: {}.'.format(num, factor, result), but the value of result." + }, + "correct": "a", + "explanation": "`result` is defined inside the function, so it has local scope. The line `print(result)` is outside the function and therefore cannot access that local variable.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The selected answer text is visible in bold on the rendered page; left-side option labels are partially obscured by the overlay." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q03", + "number": 3, + "topic": "1_Basics_Variables_3", + "question": "What will be printed by the following code segment?\n\ndef main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[None]", + "d": "[]" + }, + "correct": "b", + "explanation": "The function appends only elements whose type matches the type of `x`, which is `list`. Among the provided elements, only `[]` is itself a list, so the printed result is `[[]]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The right edge of the input list is slightly clipped in the rendered PNG, but the visible options and the function logic confirm the selected answer `[[]]`." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q04", + "number": 4, + "topic": "3_Function_Argument_3", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\ndef main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10']", + "b": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10', '1 * 11 = 11']", + "c": "This code produces an error as there is a missing argument when calling main.", + "d": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')" + }, + "correct": "a", + "explanation": "When `main(1)` is called, `y` uses its default value `11`. The loop runs for `i` values 1 through 10, so it returns a list of ten multiplication strings from `1 * 1 = 1` through `1 * 10 = 10`.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The left option labels are partially obscured by the overlay, but the visible answer texts and the selected outcome verify the correct option." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q05", + "number": 5, + "topic": "Functions Built-in", + "question": "Suppose you have a list called x, where:\n\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Both snippets produce [5, 4, 3, 2, 1]. The first removes duplicates and sorts the unique values in reverse order, and the second slices every second element from the reversed list.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-04.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q06", + "number": 6, + "topic": "Function Flexible Argument", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "B sums the keyword argument values, which is exactly what the function should do. A incorrectly adds the keyword names, and C iterates over keys in a way that does not match the intended structure.", + "code_context": "def main(**kwargs):\n # Sum the values passed as keyword arguments", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-04.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q07", + "number": 7, + "topic": "Dictionaries Comprehension", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {len: word for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to its length. The other options either reverse the key/value order or use invalid comprehension logic.", + "code_context": "words = ['example', 'python', 'exam']", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q08", + "number": 8, + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades:\n- The students list contains strings representing the names of students.\n- The grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears, which matches the requested dictionary. B stores lists of students per grade, so it does not produce counts.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q09", + "number": 9, + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the correct result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q10", + "number": 10, + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q11", + "number": 11, + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q12", + "number": 12, + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q13", + "number": 13, + "topic": "string - find - 3", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", so only the second occurrence remains replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q14", + "number": 14, + "topic": "string - fstring - 3", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the required sentence exactly, including the word \"and\" before the final fruit. Option A joins the list without \"and\", so it does not produce the exact requested output.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q15", + "number": 15, + "topic": "string - operations - 3", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)", + "b": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "c": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "d": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})" + }, + "correct": "a", + "explanation": "Option A builds aligned pandas Series for the local parts and domains, then returns them in a DataFrame with the correct column names. The other options either swap fields, overwrite values, or construct the DataFrame incorrectly.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q16", + "number": 16, + "topic": "6_OOP_Easy_1", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "True\nFalse", + "c": "False\nTrue", + "d": "False\nFalse" + }, + "correct": "a", + "explanation": "The name comparison is true because the object stores 'John Smith', and the gender comparison is also true because the default value 'not specified' is used when no gender is provided.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q17", + "number": 17, + "topic": "8_Datetime_Easy_2", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original code computes the difference in days between January 10 and January 1, then adds 1, yielding 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option A/B formatting is small in the rendered page and should be human-confirmed if exact punctuation matters; the correct answer is still clear from the logic of the visible options." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q18", + "number": 18, + "topic": "pandas - easy - 3", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df.loc[:, 'Age'])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df[['Player', 'Age']])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing does not accept the tuple (1, 'Age') in this form.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q19", + "number": 19, + "topic": "6_OOP_Function_1", + "question": "You have the following definition for a class called Animals:\n\nclass Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ...\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs == True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin == True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "c", + "explanation": "Both shown method implementations use the instance attributes to return the animal's sound when the relevant boolean attribute is present and the required fallback message otherwise.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The lower-left answer labels are partially obscured in the rendered PNG; option text and the selected outcome were reconstructed from the visible code blocks and question structure." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q20", + "number": 20, + "topic": "6_OOP_Hard_3", + "question": "You have the following definition for a class named Movie.\n\nclass Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ...\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute.\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and returns the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "d", + "explanation": "The first code segment is broken because it tries to add an integer directly to a list and its compare logic cannot return the other movie's title correctly. The second code segment omits self where needed and compares method objects instead of method results.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some punctuation in the non-selected code options is small in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q21", + "number": 21, + "topic": "8_Datetime_Function_1", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "b": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "c": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "d": "This code segment will work as intended." + }, + "correct": "b", + "explanation": "After the first append inside the loop, the list contains formatted date strings. On the next iteration the code tries to add a timedelta to that string, which is not allowed.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q22", + "number": 22, + "topic": "8_Datetime_Hard_3", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas module is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A builds real datetime objects using year, month, and day in the correct order and then formats each one as DD-MM-YYYY.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some small punctuation in the non-selected option snippets is hard to read in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q23", + "number": 23, + "topic": "pandas - hard - 3", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 100\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])", + "c": "Both blocks of code will work as intended.", + "d": "None of the blocks of code will work as intended." + }, + "correct": "c", + "explanation": "Both code blocks compute the rounded mean salary, derive an above-average indicator, compute salary differences from that mean, and filter the rows with positive differences.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q24", + "number": 24, + "topic": "pandas - lambda - 3", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18", + "b": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "c": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "d": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15" + }, + "correct": "a", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing 16, 17, and 18 in column C.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-17.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The option-letter area is partially obscured in the rendered PNG, but the four visible output tables were transcribed from top to bottom as options a through d." + ] + } + } + ], + "blocked_questions": [] + }, + { + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "title": "Trial Final Later-Course Focus", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/trial-final-exam-solutions-introduction-to-python-3077951.pdf", + "expected_questions": 24, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-01.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-02.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-03.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-04.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-05.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-06.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-08.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-09.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-10.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-11.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-12.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-13.png" + ], + "page_count": 13, + "duplicate_aliases": [], + "seed_sources": { + "legacy_assessment_payload_path": "data/import_payloads/post_midterm_assessments/trial-final-exam-solutions-introduction-to-python-3077951.json", + "study_db_exam_label": "Trial final exam Introduction to Python", + "study_db_exam_source": "materials/post_midterm/practice_exams_previous_years/trial-final-exam-solutions-introduction-to-python-3077951.pdf", + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review." + }, + "review_tracking": { + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "legacy_seeded_questions": 0, + "pending_vision_questions": 0 + }, + "extraction_status": "partial", + "questions": [ + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q01", + "number": 1, + "topic": "6-OOP-1", + "question": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor, then the \"mode\" attribute should be equal to \"land\".\n\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A defines an initializer with a required vehicle name and a default mode of \"land\", then stores both on the instance using self.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q02", + "number": 2, + "topic": "6-OOP-2", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The reviews are 5, 3, and 3, so the average is 11 / 3 = 3.666..., which show_rating rounds to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q03", + "number": 3, + "topic": "6-strings-1", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\n\nFor example, if:\nstudents = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 7.5.\nBernard has received a grade of 8.0.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']:.1f}.\")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {grade:.1f}.\")", + "c": "for student in students:\n print(f\"{student[\\\"Name\\\"]} has received a grade of {student[\\\"Grade\\\"]:.1f}.\")", + "d": "for student, grade in students:\n print(f\"{student} has received a grade of {grade:.1f}.\")" + }, + "correct": "a", + "explanation": "Option A iterates through each dictionary in the list and formats the student's name and grade correctly to one decimal place. The other options use the wrong iteration pattern or invalid access pattern for this data structure.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Option C's quote style is small in the rendered page and should be human-confirmed if exact punctuation matters." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q04", + "number": 4, + "topic": "6-strings-2", + "question": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character, at various places).\n\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A does not work because strings are immutable and number.replace(\"-\", \"\") returns a new string that is ignored. The function then returns the original unmodified number.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# all should return \"0205251400\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q05", + "number": 5, + "topic": "7-pandas-new_column-1", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] + df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x + df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\" + \"B\"]", + "d": "df[\"C\"] = df[\"A\" + \"B\"]" + }, + "correct": "a", + "explanation": "Option A performs elementwise addition between columns A and B and stores the result in column C. The other options either misuse map, index into the columns object incorrectly, or look for a non-existent combined column name.", + "code_context": "df has numeric columns \"A\" and \"B\"; column \"C\" should contain their sum.", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q06", + "number": 6, + "topic": "7-pandas-selection-1", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that only contains those elements of column \"B\" in df that have an even-numbered index. Which of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters rows whose index is even and selects column B while keeping the result as a DataFrame by using [[\"B\"]]. Option D would return a Series, not a DataFrame, and the other options do not select the requested data correctly.", + "code_context": "df printed as:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q07", + "number": 7, + "topic": "7-pandas-sorting-1", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\n\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False)[[\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A sorts the entire DataFrame by index in descending order and would include rows 5 and 1 as well, so it would not match df2. The other options all produce rows 4, 3, and 2 with columns A, C, and D.", + "code_context": "print(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q08", + "number": 8, + "topic": "7-pandas-string-1", + "question": "There is a pandas Series called s, which contains Dutch municipality and corresponding province names, separated by a semicolon and a whitespace. The following, for example, is an element of this Series: \"Amsterdam; Noord-Holland\".\n\nYou'd like to create a new Series that only contains the municipality names from s in the same order. Which of the following code lines will achieve what you want?", + "options": { + "a": "s.map(lambda x: x.split(\"; \")[0])", + "b": "s.split(\"; \")[0]", + "c": "s.lambda(x.split(\"; \"))", + "d": "s.str[:9]" + }, + "correct": "a", + "explanation": "Option A applies split('; ') to each element in the Series and takes the first part, which is the municipality name. The other options either do not operate elementwise or do not reliably extract the municipality name.", + "code_context": "Example element in s:\n\"Amsterdam; Noord-Holland\"", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q09", + "number": 9, + "topic": "8-datetime-1", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "\"03/02/2013\" matches %m/%d/%Y and gives month 3, \"03.02.2013\" matches neither branch and becomes None, and \"03-02-2013\" matches %d-%m-%Y and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q10", + "number": 10, + "topic": "8-datetime-2", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives the zero-based offset in days, and adding 1 converts it to the day number within the year. The other options either return or manipulate timedeltas incorrectly or use an invalid date.", + "code_context": "Example target behavior:\nday_of_year(datetime(2022, 2, 1))\n# returns 32", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q11", + "number": 11, + "topic": "8-dict_comprehension-1", + "question": "You have a list of strings called list_1, in which every element is unique.\n\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the dictionary comprehension that maps each string to its length. Option B creates a list, option C creates a set, and option D reverses the intended key-value relation.", + "code_context": "list_1 contains unique strings.", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q12", + "number": 12, + "topic": "8-list_comprehension-1", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\n\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[letter.upper() for letter in list_1 if letter.islower() else letter.lower()]", + "c": "[letter.lower() for letter in list_1 if letter.isupper()] + [letter.upper() for letter in list_1 if letter.islower()]", + "d": "[letter.capitalize() for letter in list_1 if not letter.iscapitalized()]" + }, + "correct": "a", + "explanation": "Option A flips the case of each letter while preserving the original order of the list. The other options either have invalid comprehension syntax, change the order, or use a non-existent string method.", + "code_context": "list_1 contains letters with mixed case.", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option D uses the method name exactly as it appears in the rendered page; it looks like 'iscapitalized()'." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q13", + "number": 13, + "topic": "Basic logic", + "question": "Suppose you have three variables x, y, z as follows:\n\nx = 'x'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string 'x' is not equal to the integer 3 or the float 3.0, so the first and third comparisons are False. The integer 3 and float 3.0 are equal in Python, so the second comparison is True. The chained comparison is False because x == y is False.", + "code_context": "x = 'x'\ny = 3\nz = 3.0\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q14", + "number": 14, + "topic": "Basic loop", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. In the first iteration, just take the previous number to be 0.\n\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e. only the sums).", + "options": { + "a": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "b": "i = 0\nwhile i <= 10:\n print(i + (i - 1))\n i += 1", + "c": "Both of the above", + "d": "Neither of the above" + }, + "correct": "a", + "explanation": "A keeps track of the previous number and prints each sum correctly from 1 + 0 through 10 + 9. B does not use the required previous-value logic and prints the wrong sums.", + "code_context": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q15", + "number": 15, + "topic": "Basic scope", + "question": "Executing the following program will produce an error. Why?\n\ndef cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "options": { + "a": "Result is a local variable and cannot be referenced outside of the function", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "result is created inside the function, so it is local to cube and is not available at the top level where print(result) is executed.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q16", + "number": 16, + "topic": "List lambda", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\n\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "list_1[0](1, 2) returns 3 and list_1[1](1, 2) returns 2, so the expression becomes 3 ** 2, which is 9.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q17", + "number": 17, + "topic": "List logic", + "question": "You have the following function called main:\n\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat are the outputs of the following lines:\nmain([[], (), []])\nmain([[1], [2, 2], [3, 3, 3]])\nmain([[1], [2], [3]])", + "options": { + "a": "True\nTrue\nTrue", + "b": "True\nFalse\nTrue", + "c": "True\nFalse\nFalse", + "d": "False\nFalse\nTrue" + }, + "correct": "a", + "explanation": "For the first call, each element has length 0, so y becomes [True, True, True] and the comparison is True. In the second and third calls, each element has non-zero length, so y becomes [False, False, False] and the chained equality is also True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q18", + "number": 18, + "topic": "List loop", + "question": "How do you break a list into a list of lists, in which a sub-list consists of 3 values each?\n\nFor example, if the original list x is:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nthen how would you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:i + 3] for i in range(0, 7, 3)]", + "b": "y = [x[0::3] for i, enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of the above works" + }, + "correct": "a", + "explanation": "A slices the list into consecutive groups of three elements. B does not produce the required nested lists.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q19", + "number": 19, + "topic": "trial-dictionary-1", + "question": "You have to write a function called main that accepts a dictionary as an input argument. Both the keys and the values of the input are integers.\n\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary, whose keys are smaller than, or equal to, the output key in question.\n\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\n\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "b": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "c": "Both of the above works as intended", + "d": "None of the above work as intended" + }, + "correct": "c", + "explanation": "Option A builds cumulative sums over the sorted keys, and option B directly computes the sum of values whose keys are less than or equal to each output key. Both produce the intended dictionary values.", + "code_context": "Example target behavior:\nmain({5: 1, 2: 5, 4: 2})\n# returns a dictionary equal to {5: 8, 2: 5, 4: 7}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q20", + "number": 20, + "topic": "trial-dictionary-2", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) creates key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q21", + "number": 21, + "topic": "trial-dictionary-3", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\n\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not key-value pairs, so `for key, value in d1:` does not work as intended. The other three options all sum the dictionary values and print the same result.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q22", + "number": 22, + "topic": "trial-functions-1", + "question": "You have the following string\nx = 'Amsterdam'\n\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method must be called on the string object itself, so `x.count('a')` is the correct form. In 'Amsterdam', there is one lowercase 'a', while the initial uppercase 'A' is not counted.", + "code_context": "x = 'Amsterdam'", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q23", + "number": 23, + "topic": "trial-functions-2", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "For option A, the function returns 6 + 7 + 8 + 9 = 30. For option B, it returns 1 + 4 + 9 + 16 = 30. Both calls therefore produce 30.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q24", + "number": 24, + "topic": "trial-functions-3", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\n\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C imports the module under the name `constants`, but then tries to access `math.pi`, where `math` is not defined. The other options all reference pi correctly and would print the correct area.", + "code_context": "Area formula: πr²", + "provenance": { + "origin": "vision_review_drop", + "origin_path": "data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json", + "capture_method": "vision_model_manual_review", + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ], + "blocked_questions": [] + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/exam_question_bank_completeness.json b/data/vision_exam_pipeline/exam_question_bank_completeness.json new file mode 100644 index 0000000..121f2ef --- /dev/null +++ b/data/vision_exam_pipeline/exam_question_bank_completeness.json @@ -0,0 +1,85 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T18:24:26Z", + "question_bank_schema_version": "1.0", + "overall_status": "complete", + "summary": { + "canonical_exam_count": 7, + "complete_exam_count": 7, + "incomplete_exam_count": 0, + "reviewed_question_count": 168, + "expected_question_count": 168 + }, + "exams": [ + { + "exam_id": "sample-final-plus-answers", + "title": "2025 Sample Final Plus Answers", + "expected_questions": 24, + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "missing_without_reason": [], + "status": "complete" + }, + { + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "title": "2022 Final Exam", + "expected_questions": 24, + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "missing_without_reason": [], + "status": "complete" + }, + { + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "title": "2023 Trial Final Study Guide", + "expected_questions": 24, + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "missing_without_reason": [], + "status": "complete" + }, + { + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "title": "2024 Trial Final", + "expected_questions": 24, + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "missing_without_reason": [], + "status": "complete" + }, + { + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "title": "2023 Resit Exam Guidelines", + "expected_questions": 24, + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "missing_without_reason": [], + "status": "complete" + }, + { + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "title": "2023 Resit Solutions", + "expected_questions": 24, + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "missing_without_reason": [], + "status": "complete" + }, + { + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "title": "Trial Final Later-Course Focus", + "expected_questions": 24, + "present_questions": 24, + "blocked_questions": 0, + "human_confirmed_questions": 0, + "missing_without_reason": [], + "status": "complete" + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/page_manifest.json b/data/vision_exam_pipeline/page_manifest.json new file mode 100644 index 0000000..5e8d688 --- /dev/null +++ b/data/vision_exam_pipeline/page_manifest.json @@ -0,0 +1,224 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:26Z", + "policy": { + "vision_only_question_capture": true, + "text_layer_extraction_forbidden": true, + "ocr_forbidden": true, + "page_rendering_allowed": true + }, + "duplicate_aliases": [ + { + "exam_id": "final-exam-solutions-for-python-programming-course-code-308088-308234", + "duplicate_of": "final-exam-solutions-for-python-programming-62oop21", + "title": "2022 Final Exam Duplicate Copy", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-solutions-for-python-programming-course-code-308088-308234.pdf" + } + ], + "exams": [ + { + "exam_id": "sample-final-plus-answers", + "title": "2025 Sample Final Plus Answers", + "group": "current-year", + "pdf_path": "../course_files_after_midterm/Sample Final plus answers.pdf", + "expected_questions": 24, + "page_count": 31, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-01.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-02.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-03.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-04.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-05.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-06.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-07.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-08.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-09.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-10.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-11.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-12.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-13.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-14.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-15.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-16.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-17.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-18.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-19.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-20.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-21.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-22.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-23.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-24.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-25.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-26.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-27.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-28.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-29.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-30.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-31.png" + ], + "render_status": "reused_existing_pages" + }, + { + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "title": "2022 Final Exam", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-solutions-for-python-programming-62oop21.pdf", + "expected_questions": 24, + "page_count": 15, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-02.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-03.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-04.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-05.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-06.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-07.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-08.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-09.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-10.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-11.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-12.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-13.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-14.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-15.png" + ], + "render_status": "reused_existing_pages" + }, + { + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "title": "2023 Trial Final Study Guide", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-study-guide-trial-python-basics-2023.pdf", + "expected_questions": 24, + "page_count": 17, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-02.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-03.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-04.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-06.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-07.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-08.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-09.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-10.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-11.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-12.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-13.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-14.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-15.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-16.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-17.png" + ], + "render_status": "reused_existing_pages" + }, + { + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "title": "2024 Trial Final", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/introduction-to-python-trial-final-exam-solutions-py22.pdf", + "expected_questions": 24, + "page_count": 17, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-01.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-02.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-03.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-04.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-06.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-07.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-08.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-09.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-10.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-11.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-12.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-13.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-14.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-15.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-16.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-17.png" + ], + "render_status": "reused_existing_pages" + }, + { + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "title": "2023 Resit Exam Guidelines", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.pdf", + "expected_questions": 24, + "page_count": 17, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-01.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-02.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-07.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-08.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-09.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-10.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-11.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-12.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-13.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-14.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-15.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-16.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-17.png" + ], + "render_status": "reused_existing_pages" + }, + { + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "title": "2023 Resit Solutions", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/resit-solutions-for-introduction-to-python-35761538.pdf", + "expected_questions": 24, + "page_count": 17, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-01.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-02.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-03.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-04.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-06.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-07.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-08.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-09.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-10.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-11.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-12.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-13.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-14.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-15.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-16.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-17.png" + ], + "render_status": "reused_existing_pages" + }, + { + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "title": "Trial Final Later-Course Focus", + "group": "previous-years", + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/trial-final-exam-solutions-introduction-to-python-3077951.pdf", + "expected_questions": 24, + "page_count": 13, + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-01.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-02.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-03.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-04.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-05.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-06.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-08.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-09.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-10.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-11.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-12.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-13.png" + ], + "render_status": "reused_existing_pages" + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/plan_after_manual_synthesis.md b/data/vision_exam_pipeline/plan_after_manual_synthesis.md new file mode 100644 index 0000000..22c5054 --- /dev/null +++ b/data/vision_exam_pipeline/plan_after_manual_synthesis.md @@ -0,0 +1,283 @@ +# Feedback on suggested edits +### 1. Essential String Methods and Indexing Reference + +Yes, add this. + +### 2. Output Formatting and String Construction + +Yes, add this. + +### 3. Boolean String Predicates + +Yes, add this, but only very briefly. Perhaps it's good to have a table with incorrect/correct use (if that's something the questions asked often). + +### 4. Iteration Helpers and Basic Operator Traps + +Add this. + +### 5. Comprehension Syntax Reference + +Yes, add this, but see if it's possible to get the best of both worlds. + +Perhaps even consider doing both: + +- a table with syntax +- a table with tiny examples that explain what that syntax does + +In the next pass we'll see if agents actually use it (and which one they use more) so we can determine what the better approach is. + + +### 6. Dictionary Construction and Iteration Patterns + +Yes, add this. + +### 7. Pandas Selection and Indexing Rules + +Add this. + +Considering that "Week 5 already has some very strong exact-match snippets." --> consider whether it's possible to absorb some (parts of) these snippets into those of week 5 + +### 8. Pandas Filtering, Aggregation, and Column Arithmetic + +Please edit/expand existing + +### 9. Lambda, `map`, and `apply` + +Add! + +### 10. Datetime Parse/Format Cheat Sheet + +Add please + +### 11. Datetime Object-vs-String Arithmetic + +but preferably as part 2 of the same datetime reference family rather than a disconnected standalone card. (like, make it separately selectable, so that users can choose which parts they want) + +### 12. OOP Fundamentals: `self`, `__init__`, Attributes, and Defaults + +Add (see if you can absorb (parts of) some of the existing snippets into this one) + +### 13. OOP Comparison Logic + +add or merge into existing + +### 14. Flexible Arguments, Returns, and `kwargs` + +Please add + +### 15. Return-Value and Scope Cleanup + +Please edit existing + +### 16. Exact-Match Retrieval Fixes + +Sure! But don't spend too much time on this. Remember, people will not be able to search during an exam. They will mostly just create a cheat sheet beforehand and then print it out. Improving the search_text will improve how quickly agents can find relevant snippets and will be useful for generating insights about which snippets are relevant, but the end user will barely use this, if at all. + +We should also be careful not to bias the agents to certain snippets simply because they arbitrarily have better search terms. + +So please make sure that the search_text treats all the different snippets fairly. + + +## Next Steps + +### (1) Architecture changes to keep in mind +Many topics span multiple different weeks, so it's good to rework the data architecture and come loose from the strict week > topic > snippets structure + +Instead, the new snippets should have metadata `main_theme` (just one) `related_themes` (can be multiple), `main_week` (just one) and `related_weeks` (can be multiple). + +Old snippets will also be ported that arcitecture eventually. + +However, for this current phase, these architecture changes should be treated as metadata-only changes to keep in mind while creating/improving snippets. They should not turn into a larger UI refactor or a full data-model overhaul yet. The current priority is completeness of the snippet corpus. The bigger architecture/UI changes can happen later, once the new snippets are in place and the next grading pass gives better evidence about how the topics should actually be grouped. + +### (2) Creating new snippets + +The next step is to actually create the new snippets that were missing, based on the earlier findings (that I agree with). The goal here is to make all the snippets that would answer all the questions. + +Snippet considerations that apply to all: + +* they should be consise and clear, not verbose +* they should convey information in the most efficient way possible (sometimes that's a table, other times it's a text-explanation, or a code example, or a combination of different elements) +* snippets should have separate selectable elements for different bits of information. This allows users to choose exactly what they want to include or exclude, and use the available space on their cheat sheet for only the bits that they need. For example, a text-explanation, a table, a code example, and another table should have different selectable items for all the unique elements. +* snippets should assume two audiences and create different selectable elements for the two. (1) people with some prior knowledge about python that mostly need references about syntax and (2) people with very little prior knowledge that need more complete explanations. A snippet can convey the same information twice (once in compact form and once in more complete explanation), and these should be separately selectable. + +But there are some important guardrails here: + +* do not split pieces too aggressively just because it is technically possible. Split a snippet into separate selectable pieces only when a user might reasonably want one part without the other. +* avoid exploding the total number of tiny pieces. If two parts are only useful together, keep them bundled. +* for the "two audiences" idea, the preferred pattern is usually: + * one compact reference piece + * one optional explanation piece +* only include both when they genuinely add different value. If the explanation is barely adding anything, do not duplicate the same information just for the sake of it. + +#### Snippet element: code examples + +It's good to keep in mind that the current snippets are based on the same exams that they are being evaluated against. But the goal is to design snippets that would also work really well for the next exam (that is not yet known). + +Therefore, I think the snippets can use some different kinds of examples but should avoid other kinds. + +**Use these example types** + +* short pieces of correct syntax that efficiently demonstrate how the syntax works +* short pieces of incorrect syntax that efficiently demostrate how students can recognise when errors would occur +* somewhat longer examples that provide insights about many different topics / types of syntax, or clearly demonstrate common (in)correct patterns so students can easily recognise them + +--> if examples are the best way to show a specific concept/type of syntax, use already-exisitng examples from the source material or (more likely): generate one or a few example lines of code to demonstrate it quickly. +--> only if the same, or very similar questions appear accross multiple exams, it might be good to make a "common exam question"-style snippet with an example. Generate an example that synthesises multiple exam questions into one. + + +**Formatting** + +Code examples can be: + +* inline for very simple explanations (use `code-snippet` backticks) +* as a small code block + +```python +slightly longer code-piece # this is an example +wow there are two lines! +``` + +* In a markdown-style table, for example with headers like "code" and "output", or "correct" "incorrect" "explanation", or any other table format that makes sense + +#### Snippet element: reference table + +I really want to make this more common. Reference tables are a really good way to summarize information very efficiently. + +As mentioned above, reference tables can include examples of (in)correct syntax and their output/what it does, but also other things that can be handy to know on an exam. This is very often the best way to present information so that it's easy to understand at a glance while still being detailed + +#### Snippet element: textual explanation + +Adding textual explanation of what syntax does, what things are (in)correct and why, or other clarification can be a good way to make things clearer. However, it can also add bloat. So, if there is a texual element to a snippet, make sure it's selectable separately from the rest so that people don't *have* to include it if they don't need the extra explanation. + +Textual explanations should still always be brief and straight to the point. + +#### Snippet element: something else + +It is very possible that there is a different way to more efficiently display information. Please feel free to come up with other snippet element types! Make sure they: + +* work well on a printed cheat sheet +* align with other considerations explained in the previous sections + + +### (3) Curation pass and building up the new, complete database: unifying with near-duplicates and removing low-quality snippets from the available corpus + +After the new snippets are created, there should be a pass to reduce the available corpus to only high quality snippets. Agents should manually curate them. + +For the remainder of this section, I will use certain terms. And this is what I mean by them: + +* a "piece" is one element that a user can select. A "piece" is the smallest unit in the database. It is a single element that a user can select for their cheat sheet. This is for example, one reference table, one textual explanation, one code example, etc. +* a "snippet" is a bundle of different "pieces" that logically belong together. So, it can be a bundle that include a longer textual explanation, a shorter textual explanation, a table, and one or a few code examples that all relate to the same thing. +* a "topic" is a collection of "snippets" that relate to that topic. A topic can be, for example, "working with values" or "loops" + + +The goal of this pass is to combine the best snippets from the old dataset with the new dataset into an untimate final dataset with only the highest value and highest quality snippets. + +Agents should manually curate this to: + +* create snippets that bundle all the loose pieces from the old and new datasets +* merge near-duplicates into one cannonical snippet +* minimize duplication of information, but retain all the information that is in the old + new snippets + +for the new dataset, we simplify the metadata that we show on the frontend. We no longer show where snippets came from (except when they're from a specific past exam). And we change the canonical type of snippet to only be "past exam question" or "general_snippet". This allows us to be more loose with merging multiple pieces into into one snippet, or dropping low-value pieces. + +For example, notebook cells are very often low value and are often better merged into a reference table, or dropped alltogether if they don't add anything new. + +We'll also drop the "key points" section and instead allow these key points to be merged into a bigger canonical snippet or including it into a reference table. + +We'll also drop the specific "code examples" section, and instead prefer including it into a larger canonical snippet or transforming it into a reference table to more efficiently give the same information. + +It is, however, important that we don't degrade the depth or breadth of information. We simply transform the existing information into a more compact form optimised for a cheat sheet. In some cases, retaining code snippets how they are is the best call, but it should always be considered wehether there is a better way. When in doubt, keep the old one around, but also make a more compact version and let the user pick which they like best. + +Also, this curation pass should be conservative before the next grading pass: + +* merge obvious near-duplicates early +* improve weak snippets early +* but do not aggressively hard-prune snippets from the available corpus yet + +The reason is that after the new snippets are added, the next grading pass will provide much better evidence about what is actually low-value, redundant, or unnecessary. So, before that grading pass, the bias should be toward retaining information unless there is a very clear reason to remove it. + +### (4) Snippet grading pass + +This will be slightly different than the original plan. Mostly because I realise that the snippets often contain real past exam examples (and the past exams are exactly what the agents are grading the snippets against). + +What should happen is: each exam question is considered individually. The agent should imagine they have almost no prior knowledge about how python works. + +For each question, the agent should first determine: + +* is there a past exam question example in the snippets/pieces that is (near-)identical to this question (yes/no; if yes, which one(s)) + +Then, excluding the near-identical past exam question piece: + +* which 1 snippet provides the highest value for being able to answer this question? + * from that one snippet, select between 1 and 3 (inclusive) pieces that are most critical +* which other 1-2 snippet(s), beside the number 1, provide the highest value for being able to answer this question? +* what is the minimal set of snippets that I would need to be able to confidently answer this question? + * from that minimal set of snippets, which pieces would I need? + + +--> for all these questions, the agent should provide a short reason. We can use this for a sanity check and to see whether the agent understood the instructions. + +After this pass is done, we have great insight into + +* which questions repeat often (if different questions have the same near-identical past exam questions, we know that it's likely they'll ask that question again) +* which snippets provide the highest value +* which pieces are most important + +### (5) Topic-categorisation pass + +It's nice that we have all that data about the snippets, but we also need to use it for our beautiful cheat sheet builder. + +we need to do a couple of things: + +**Identify topics** + +Here, we identify which snippets belong together under one topic. We know this based on (1) common sense, but we can also be informed by (2) which snippets were often used together to answer one question. For example, if snippets A, B and C were often used together in the minimal set of snippets, and snippets x, y and Z were also often used together, then we can group A, B and C under one canonical main_topic and snippets x, y and z into another main_topic. + +We'll probably end up with somewhere between 20-40 main_topics + +**create parent_topic** + +To make the UI easier to navigate, i think we should put the topics into parent_topic entries. This will replace the "week" (1-6) that we currently have. So I think we should have at least 6 and at most 10 parent topics to keep a usable structure. + +one parent topic can have between 2 and 7 main topics (aim for exactly 5). + +And the main topic then houses the snippets + +**Assign a main_topic to each snippet** + +This is relatively easy for the snippets that were cited often by the agents during the snippet grading pass, but for the snippets where there isn't overwhelming evidence, pick the one that makes most sense. + +**Assign a week to each of the snippets** + +This is very easy for the already-existing databse: they already have a week assigned to them. For the other ones, just pick one that makes most sense. This is not very important because the week explorer is not a priority + +### (6) Snippet-ranking pass + +We do this based on the findings of the snippet grading pass. + +I think we should rethink the way that snippets are presented. Now, it's just too much. We have: + +- common exam questions +- key points +- code examples +- recommended snippets +- additional snippets + +I want to change it to: + +- **Expect these questions**: shows snippets that were marked as near-identical to an exam question at least twice. The snippets that were marked most often appear at the top, and a maximum of 5 snippets is shown initially. At the bottom of this section, there is a button with "show more" upon which the page extends and shows the complete list of all the snippets that were marked at least twice. Naturally, there also is a "hide" or "show less" button as well. +- **Highest value snippets**: shows snippets based on how often they were included as top 1, or top 2/3 + - The snippets are ranked based on a score that is computed in the backend. Each time a snippet is marked as top 1 it gets 1.5 point. Each time a snippet is marked as top 2/3 it gets 1 point. + - This section initially shows a variable amount of snippets depending on how the points were distributed in that main_topic. The cumulative amount of the shown snippets should be at least 50% of the total points in that main_topic, but only the minimum amount of snippets to satisfy that requirement + - An exception is when there are less than 3 snippets that cumulatively have more than 50% of the points. In that case, there are 3 snippets shown. + - There is a "show more" button as well to expand to all the snippets that have at least 1 point. Of course, also a "show less" button. +- **Don't forget about**: this section shows the snippets that were never marked as top 1/2/3, but that WERE included in the minimal set of snippets needed to answer a question. It should show the top 5 snippets based on how often they were marked as minimal required. Again, with a "show more" and "show less" button. +- **Maybe you'll need these, you never know**: shows the list of snippets that were never included in top 1/2/3, and never marked as minimal required. Rank them on how many different unique selectable items they have and what kind (you can think of the exact algorithm yourself). + - snippets with past exam questions or reference tables should be promoted a bit more to the top + - snippets with only text should be ranked lower +- show the top 5, and have a show less/more button as well. + +For this last ranking bucket, be careful not to reward bloat. Ranking should not simply promote snippets because they have more selectable pieces. Use some kind of diminishing-return logic so that very large snippets are not automatically treated as higher value just because they contain more elements. Reference tables and past exam questions can be promoted somewhat, but long bloated snippets should not be unfairly rewarded. + + + diff --git a/data/vision_exam_pipeline/review_drops/README.md b/data/vision_exam_pipeline/review_drops/README.md new file mode 100644 index 0000000..5dd04a0 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/README.md @@ -0,0 +1,50 @@ +# Review Drops + +Agents doing vision-only exam capture should write one JSON file per batch here, then merge it with: + +```bash +python3 scripts/vision_exam_pipeline.py merge-review-drop --input data/vision_exam_pipeline/review_drops/.json +``` + +Contract: + +```json +{ + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_updates": [ + { + "number": 8, + "topic": "short topic label", + "question": "full question text", + "options": { + "a": "option text", + "b": "option text", + "c": "option text", + "d": "option text" + }, + "correct": "a", + "explanation": "brief explanation of why the answer is correct", + "code_context": "optional code block or empty string", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages//page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} +``` + +Rules: + +- Use only rendered PNG pages as source material. +- Do not use OCR, `pdftotext`, or any deterministic text extraction. +- Keep question numbering exact. +- Preserve answer options faithfully. +- Leave `code_context` empty when there is no meaningful code block to preserve. diff --git a/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json new file mode 100644 index 0000000..ac37fb7 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-manual-q06-q11.json @@ -0,0 +1,161 @@ +{ + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_updates": [ + { + "number": 6, + "topic": "7-pandas-2", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the difference of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] - df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x - df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\"] - df.columns[\"B\"]", + "d": "df[\"C\"] = df.apply(df[\"A\"] - df[\"B\"])" + }, + "correct": "a", + "explanation": "Subtracting one numeric Series from another directly creates the elementwise difference needed for column C.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "number": 7, + "topic": "7-pandas-3", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 8.7 4.6 9.5 7.0\n2 7.3 1.5 6.3 7.1\n3 4.3 9.0 2.9 3.3\n4 4.8 2.5 5.1 3.0\n5 1.6 1.4 6.7 3.5\n6 2.4 3.7 7.6 1.3\n\nSuppose that you'd like to create a new Series that only contains those elements of column \"D\" of df that are smaller than 5.0. So the Series should look like this, when printed:\n\n3 3.3\n4 3.0\n5 3.5\n6 1.3\nName: D, dtype: float64\n\nWhich of the following code lines will not achieve what you want?", + "options": { + "a": "df.loc[2:6, df.columns[-1]]", + "b": "df.loc[df[\"D\"] < 5, \"D\"]", + "c": "df.loc[3:6, \"D\"]", + "d": "df.iloc[2:6, 3]" + }, + "correct": "a", + "explanation": "Option A slices rows 2 through 6 from the last column but does not filter out values that are 5.0 or larger, so it includes values that should not be in the result.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "number": 8, + "topic": "7-pandas-4", + "question": "You have two DataFrames: df1 and df2. They look like this when printed:\n\nprint(df1)\n\n Age Height Female City Language\n0 23 167 True Berlin German\n1 36 175 True Frankfurt German\n2 17 182 False Antwerpen Dutch\n3 25 177 True Eindhoven Dutch\n4 36 178 False Lyon French\n5 52 185 False Basel German\n6 46 168 True Innsbruck German\n\nprint(df2)\n\n Age Height Female City Language\n5 52 185 False Basel German\n4 36 178 False Lyon French\n1 36 175 True Frankfurt German\n6 46 168 True Innsbruck German\n0 23 167 True Berlin German\n\nWhich of the following code segments could have created df2 from df1?", + "options": { + "a": "df1.loc[df1[\"Language\"].isin([\"French\", \"German\"])].sort_values(\"Height\", ascending=False)", + "b": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_values(\"Age\", ascending=False)", + "c": "df1.loc[~df1[\"Language\"].isin([\"Dutch\"]), [\"Age\", \"Height\", \"City\", \"Language\"]].sort_index(ascending=False)", + "d": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_index(axis=1)" + }, + "correct": "a", + "explanation": "Option A filters out the Dutch rows and then sorts the remaining rows by Height in descending order, matching df2 exactly.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "number": 9, + "topic": "8-comprehensions-1", + "question": "You have a list of mountain peaks and their heights in meters, all formatted as \"[PEAK NAME]: [HEIGHT]m\". For example, a few elements of the list are:\n\"Denali: 6,190m\", \"Aconcagua: 6,961m\", \"Kilimanjaro: 5,895m\", ...\n\nAs you can see, the comma (\",\") is used as a thousand separator in the height. The list is called mountains.\n\nYou'd like to create a dictionary called peaks from the mountains list. The peak names would be the keys, and the corresponding integer values. Continuing the example above, a few key-value pairs of the peaks dictionary should be:\n\"Denali\": 6190, \"Aconcagua\": 6961, \"Kilimanjaro\": 5895, ...\n\nWhich of the following two code segments achieves what you want?", + "options": { + "a": "peaks = {peak.split(\":\")[0]: int(peak.split(\": \")[1][:-1].replace(\",\", \"\")) for peak in mountains}", + "b": "names = [peak.split(\":\")[0] for peak in mountains]\nheights = [int(peak.split(\": \")[1].replace(\",\", \"\").replace(\"m\", \"\")) for peak in mountains]\npeaks = dict(zip(names, heights))", + "c": "Both code segments above achieve the intended outcome.", + "d": "Neither of the two code segments above achieves the intended outcome." + }, + "correct": "c", + "explanation": "Both solutions strip off the trailing m, remove the thousands separator, convert the height to an integer, and pair each mountain name with its numeric height.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "number": 10, + "topic": "8-comprehensions-2", + "question": "You have a dictionary called grades, in which the keys are unique student ID's (as strings) and the corresponding values are each student's Python course grades (as floats).\n\nYou'd like to create another dictionary called grade_curve, in which the keys are the 18 possible Dutch course grades (1.0, 1.5, 2.0, ..., 10) as floats, and the corresponding (integer) values are the number of students in grades who have that particular grade.\n\nTake a look at the following code segment to create the grade_curve dictionary.\n\ndutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0,\n 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}\n\nDo you think this code segment will always work as intended? If not, then why not?", + "options": { + "a": "Yes, the code will always work as intended.", + "b": "The code will not work as intended if there are certain grades that no student has received. That will lead to an error in constructing the dictionary comprehension.", + "c": "The code will not work as intended, because the keys of the grades dictionary are not used in the list comprehension inside the sum function.", + "d": "The code will not work as intended, because including a list comprehension inside a dictionary comprehension will lead to a Python syntax error." + }, + "correct": "a", + "explanation": "The inner comparison list produces True and False values for every grade entry, and sum counts the matches, including zero when no student received that grade.", + "code_context": "dutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + }, + { + "number": 11, + "topic": "8-datetime-1", + "question": "What does the following code segment print to the screen?\n\nfrom datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "options": { + "a": "26-03-2020", + "b": "04-24-2020", + "c": "15-04-2020", + "d": "05-14-2020" + }, + "correct": "a", + "explanation": "The string is parsed as 5 April 2020 using month.day.year format, and subtracting 10 days yields 26 March 2020, which is then formatted as day-month-year.", + "code_context": "from datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Captured manually from zoomed image crops without OCR." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json new file mode 100644 index 0000000..10ae029 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q01-q05-legacy-reverified.json @@ -0,0 +1,131 @@ +{ + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_updates": [ + { + "number": 1, + "topic": "OOP Fundamentals", + "question": "Take a look at the following class definition.\n\nclass Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nGiven the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\nWhy?", + "options": { + "a": "The first argument (my_flight) should not have been passed to the set_date method in Code line 2.", + "b": "The capacity of the flight is not specified as an argument in Code line 1.", + "c": "The argument self is missing in Code line 1.", + "d": "The date string passed as an argument in Code line 2 represents an invalid date." + }, + "correct": "a", + "explanation": "set_date is an instance method, so Python passes self automatically. Passing my_flight explicitly adds an extra argument and causes the error.", + "code_context": "class Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\")\nmy_flight.set_date(my_flight, \"29-02-2022\")", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-02.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 2, + "topic": "OOP Fundamentals", + "question": "You have the following definition for a Book class.\n\nclass Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)\n\nSuppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book. The compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?", + "options": { + "a": "def compare(self, other):\n avg_better = self.average_score() > other.average_score()\n no_fewer_reviews = self.num_reviews() >= other.num_reviews()\n if avg_better and no_fewer_reviews:\n return self.title\n elif not avg_better:\n return other.title\n else:\n return None", + "b": "def compare(self, other):\n for first, second in [(self, other), (other, self)]:\n avg_better = first.average_score() > second.average_score()\n no_fewer_reviews = first.num_reviews() >= second.num_reviews()\n if avg_better and no_fewer_reviews:\n return first.title\n return None", + "c": "Both methods above compare the book objects as intended.", + "d": "Neither of the two methods above compare the book objects as intended." + }, + "correct": "b", + "explanation": "B checks whether either book is better than the other and returns that title, otherwise it returns None. A can incorrectly return the other book even when neither book is better.", + "code_context": "class Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-02.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 3, + "topic": "Strings", + "question": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?", + "options": { + "a": "def get_tld(url):\n url_1 = url.split(\".\")[-1]\n return url_1.split(\"/\")[0]", + "b": "def get_tld(url):\n url_1 = url.split(\"//\")[1]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]", + "c": "def get_tld(url):\n return url.split(\"//\")[1].split(\"/\")[0].split(\".\")[-1]", + "d": "def get_tld(url):\n url_1 = url[url.find(\"www\") + 2:]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]" + }, + "correct": "a", + "explanation": "A splits on the last dot first, which leaves the page extension rather than the domain. The other options isolate the host name first and then extract the final dot-separated part.", + "code_context": "def get_tld(url):\n # Extract the top-level domain from a URL string", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-03.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 4, + "topic": "Strings", + "question": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "def is_anagram(word_1, word_2):\n return sorted(list(word_1.replace(\" \", \"\").lower())) == sorted(list(word_2.replace(\" \", \"\").lower()))", + "b": "def is_anagram(word_1, word_2):\n return word_1.replace(\" \", \"\").lower().sort() == word_2.replace(\" \", \"\").lower().sort()", + "c": "def is_anagram(word_1, word_2):\n return list(word_1.replace(\" \", \"\").lower()).sort() == list(word_2.replace(\" \", \"\").lower())", + "d": "def is_anagram(word_1, word_2):\n return sorted(list(word_1)).replace(\" \", \"\").lower() == sorted(list(word_2)).replace(\" \", \"\").lower()" + }, + "correct": "a", + "explanation": "A removes spaces, lowercases both strings, and compares the sorted letters. The other options misuse sort() or apply string operations to list objects in the wrong order.", + "code_context": "def is_anagram(word_1, word_2):\n # Compare the same letters in normalized, sorted form", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-03.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 5, + "topic": "Pandas", + "question": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "s.map((s - s.mean())**2)", + "b": "(s - s.mean())**2", + "c": "s.map(lambda x: (x - s.mean())**2)", + "d": "(s - s.mean()).map(lambda x: x**2)" + }, + "correct": "a", + "explanation": "A is not the right way to apply the squared-difference expression to each element of the Series. B, C, and D all produce the desired squared differences.", + "code_context": "# s is a pandas Series of floats", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-04.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json new file mode 100644 index 0000000..38b4c8b --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q12-q15.json @@ -0,0 +1,105 @@ +{ + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_updates": [ + { + "number": 12, + "topic": "8-datetime-2", + "question": "Suppose you have the following definition for a Meeting class, which records basic information about meetings in a calendar application.\n\nYou would like to add a method called lunch_meeting to this class, which returns a boolean value indicating whether there is any overlap between the official lunchtime (12:30 - 13:00) and the time of the meeting.\n\nFor example, if you construct a Meeting object as:\nmy_meeting = Meeting('Ask for salary raise', \"25-05-2022\", start_time='12:00', length=45)\nthen the method call:\nmy_meeting.lunch_meeting()\nshould return the boolean value True.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = lunch_start + timedelta(minutes=30)\n return self.start < lunch_end and self.end > lunch_start", + "b": "def lunch_meeting(self):\n return self.start < \"13:00\" and self.end > \"12:30\"", + "c": "def lunch_meeting(self):\n return start_time <= \"13:00\" and start_time + length > \"12:30\"", + "d": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = datetime(self.date.year, self.date.month, self.date.day, 13, 0)\n return self.start >= lunch_end or self.end <= lunch_start" + }, + "correct": "a", + "explanation": "Option A constructs the lunch interval on the same date and uses the standard interval-overlap check. The other options compare datetimes to strings, reference names that are not in scope, or use the non-overlap condition instead.", + "code_context": "from datetime import datetime, timedelta\n\nclass Meeting:\n def __init__(self, topic, date, start_time=\"09:00\", length=30):\n self.topic = topic\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day,\n int(start_time.split(':')[0]), int(start_time.split(':')[1]))\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 13, + "topic": "Basic logic 2", + "question": "Suppose you have a variable x which contains a list of tuples, as follows:\n\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nChoose the correct output for the following line of code.\n\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "options": { + "a": "True", + "b": "False", + "c": "NameError", + "d": "SyntaxError" + }, + "correct": "a", + "explanation": "The left-hand side is 2 * 3 = 6 and the right-hand side is 8 - 2 = 6, so the comparison evaluates to True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 14, + "topic": "Basic loop 2", + "question": "Which of the following code segments will print every even number between 0 and 20 (including 0 and 20) to the screen?", + "options": { + "a": "for i in range(0, 20):\n if i % 2 == 0:\n print(i)", + "b": "i = 0\nwhile i <= 20:\n if i % 2 == 0:\n print(i)\n i += 1", + "c": "for i in list(range(0, 20)):\n print(i if i % 2 == 0 else None)", + "d": "i = 0\nwhile i < 21:\n print(i)\n i += 1" + }, + "correct": "b", + "explanation": "Option B checks every integer from 0 through 20 inclusive and prints only the even ones. Option A never reaches 20, option C also prints None for odd numbers, and option D prints every number.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 15, + "topic": "Basic scope 2", + "question": "Choose the correct statement about the program below:", + "options": { + "a": "a is a global variable. b, c, d are local variables.", + "b": "a, b are global variables. c, d are local variables.", + "c": "a, b, c, d are global variables.", + "d": "a, c, d are global variables. b is a local variable." + }, + "correct": "a", + "explanation": "`a` is defined at module level, so it is global. `b` is local to `outer`, and `c` and `d` are local to `inner`.", + "code_context": "a = 1\ndef outer(b):\n b = 2\n def inner(c):\n d = 3\n return a + c + d\n return inner(4) + b", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json new file mode 100644 index 0000000..dcd1291 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q16-q19.json @@ -0,0 +1,106 @@ +{ + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_updates": [ + { + "number": 16, + "topic": "final-dictionary-1", + "question": "You have to write a function called main, which takes a list of unique integers as an argument and returns a dictionary.\n\nThe output dictionary should consist of all key-value pairs for which the key is an element of the input list and the value is the next element of the input list. When there is no \"next element\" any more, leave the key-value pair out of the dictionary.\n\nFor example, if your function is called as:\nmain([1, 3, 2, 4])\nthen it should return the dictionary:\n{1: 3, 3: 2, 2: 4}\n\nWhich of the following programs work(s) according to the requirements?", + "options": { + "a": "def main(l1):\n result = {}\n index = 0\n while True:\n index = index + 1\n if index >= len(l1):\n break\n else:\n result[l1[index]] = l1[index + 1]\n return result", + "b": "def main(l1):\n result = {}\n for index, value in zip(l1[:-1], l1[1:]):\n result[index] = value\n return result", + "c": "Both programs work as required", + "d": "Neither of the two programs works as required" + }, + "correct": "b", + "explanation": "Option B correctly zips each element with the following element and builds the required dictionary. Option A starts at index 1 and eventually tries to access past the end of the list.", + "code_context": "main([1, 3, 2, 4])\n# should return {1: 3, 3: 2, 2: 4}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 17, + "topic": "final-dictionary-2", + "question": "What will be printed by the following program?", + "options": { + "a": "True", + "b": "False", + "c": "An error message", + "d": "None" + }, + "correct": "a", + "explanation": "Dictionary equality compares key-value contents rather than insertion order. Since both dictionaries contain the same pairs, the comparison prints True.", + "code_context": "d1 = {1: 5, 4: 6}\nd2 = {4: 6, 1: 5}\nprint(d1 == d2)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 18, + "topic": "final-dictionary-3", + "question": "d1 = {1: 2, 2: 1}\n\nThe following code segments all print exactly the same output, except for one. Which one?", + "options": { + "a": "result = 1\nfor x in d1.values():\n result *= x\nprint(result)", + "b": "result = -1\nfor x in d1.keys():\n result += d1[x]\nprint(result)", + "c": "result = 4\nfor x in d1.items():\n result = result // x[1]\nprint(result)", + "d": "result = -4\nfor x in d1:\n result /= d1[x]\nprint(result)" + }, + "correct": "d", + "explanation": "A, B, and C all print 2. Option D uses true division starting from -4, so it prints -2.0 instead, making it the odd one out.", + "code_context": "d1 = {1: 2, 2: 1}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 19, + "topic": "final-functions-1", + "question": "Suppose that you have a string called s1, which contains several letters. The letter \"x\" and the letter \"y\" occur exactly once in the string, and \"x\" always precedes \"y\".\n\nYou'd like to print out a string that looks just like s1, except that the letters \"x\" and \"y\" should be swapped.\n\nFor example, if:\ns1 = \"axbyc\"\nthen you'd like to print:\naybxc\n\nReminder: The replace string method has a third argument, which allows you to specify the maximum number of replacements you want to make, counting from left to right.", + "options": { + "a": "s1 = s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "b": "s1 = s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)", + "c": "s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "d": "s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)" + }, + "correct": "b", + "explanation": "Option B first changes the single y to x, then changes the first x from left to right back to y, which swaps the two letters. Options C and D do not assign the new string back to s1, and A changes the first replacement back incorrectly.", + "code_context": "s1 = \"axbyc\"\n# desired printed result: aybxc", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option D's trailing `print(s1)` line is implied by the rendered pattern but should be human-confirmed from the source page." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json new file mode 100644 index 0000000..c0932e6 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q20-q22.json @@ -0,0 +1,80 @@ +{ + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_updates": [ + { + "number": 20, + "topic": "final-functions-2", + "question": "Take a look at the following function definition.\n\nWhat will be returned by the following function call:\nglue(a='e', b='d')", + "options": { + "a": "ab", + "b": "cd", + "c": "ba", + "d": "dc" + }, + "correct": "c", + "explanation": "The function iterates over the keyword names in insertion order (`a`, then `b`) and prepends each key to the current result. Starting from the empty string, that produces `a`, then `ba`.", + "code_context": "def glue(**kwargs):\n result = ''\n for el in kwargs.keys():\n result = el + result\n return result", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 21, + "topic": "final-functions-3", + "question": "Take a look at the following function definition.\n\nWhat will be printed to the screen by the following code?\nprint(tester())", + "options": { + "a": "1", + "b": "-1", + "c": "0", + "d": "None" + }, + "correct": "a", + "explanation": "The default argument is `0`, which satisfies the non-negative condition, so the function returns `1` and `print` outputs `1`.", + "code_context": "def tester(i1 = 0):\n if i1 >= 0:\n return 1\n\n if i1 < 0:\n return -1", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 22, + "topic": "List lambda 2", + "question": "Assume that you have a variable called x, which contains a list of integers.\n\nWhich of the following code segments will create another list that has every element of x multiplied by 2?\n\nFor example, if\nx = [1, 2, 3, 4, 5]\nthen which of the following code segments will result in the list:\n[2, 4, 6, 8, 10]", + "options": { + "a": "list(map(lambda i : i * 2, x))", + "b": "[(lambda i : i * 2)(item) for item in x]", + "c": "y = lambda i : i * 2\n[y(i) for i in x]", + "d": "All three code segments would work as intended" + }, + "correct": "d", + "explanation": "Each option constructs the doubled list correctly: `map` with a lambda, an immediately called lambda inside a list comprehension, and a named lambda used inside a list comprehension all apply `i * 2` to every element of `x`.", + "code_context": "x = [1, 2, 3, 4, 5]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q23-q24.json b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q23-q24.json new file mode 100644 index 0000000..b5206d9 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-solutions-for-python-programming-62oop21-q23-q24.json @@ -0,0 +1,55 @@ +{ + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_updates": [ + { + "number": 23, + "topic": "List logic 2", + "question": "Which of the following programs creates a new list y, in which the elements are those elements of list x that are equal to their indices?\nYou can assume x consists of unique integers.\n\nFor example, if:\nx = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\nthen the program should create a new list y such that:\ny = [0, 3, 6, 7, 8, 10]", + "options": { + "a": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(i)", + "b": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(j)", + "c": "y = [i for i in x if i == x.index(i)]", + "d": "All three programs would work as intended" + }, + "correct": "d", + "explanation": "In A and B, whenever `i == j`, appending either `i` or `j` gives the same value because the index equals the element. In C, `x.index(i)` returns the position of `i`, so the comprehension keeps exactly the elements equal to their indices. Therefore all three programs work.", + "code_context": "x = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\n# target result:\ny = [0, 3, 6, 7, 8, 10]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 24, + "topic": "List loop 2", + "question": "Assume that you have a list called x, which is a list of multiple sub-lists containing integers.\n\nWhich of the following programs will create a new list y that is equal to the sub-list of x whose sum of elements is the highest?\n\nYou can assume that the sum of elements in each sub-list is a different number, so that there is only one that is the highest.\n\nFor example, if:\nx = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\nthen y should be:\ny = [8, 20, 300]", + "options": { + "a": "y = max(x)", + "b": "z = []\nfor i in x:\n z.append(sum(i))\ny = x[z.index(max(z))]", + "c": "x.sort()\ny = x[-1]", + "d": "y = [i for i in x if sum(i) == max(x)]" + }, + "correct": "b", + "explanation": "Option B computes the sum of each sub-list, finds the position of the largest sum, and then returns the corresponding original sub-list. The other options compare lists lexicographically or compare a numeric sum against `max(x)`, which is a list.", + "code_context": "x = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\n# target result:\ny = [8, 20, 300]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json new file mode 100644 index 0000000..e987432 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q01-q06-legacy-reverified.json @@ -0,0 +1,156 @@ +{ + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_updates": [ + { + "number": 1, + "topic": "1_Basics_Logic_2", + "question": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\n- If they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\n- If they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?", + "options": { + "a": "if destination in europe:\n print('No passport needed. Bring your ID card.')\nelse:\n print('Please bring your passport.')", + "b": "if destination in europe:\n return 'No passport needed. Bring your ID card.'\nelif destination not in europe:\n return 'Please bring your passport.'", + "c": "for country in europe:\n if destination = country:\n print('No passport needed. Bring your ID card.')\n else:\n print('Please bring your passport.')", + "d": "for country in europe:\n if destination != country:\n return 'Please bring your passport.'\n else:\n return 'No passport needed. Bring your ID card.'" + }, + "correct": "a", + "explanation": "Option A directly checks whether destination is in the list of European countries and prints the correct message in each case. The other options either use the wrong control flow or invalid syntax.", + "code_context": "europe = [...]\ndestination = ...", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 2, + "topic": "1_Basics_Scope_3", + "question": "Calling the function func_10 will produce an error. Which line of the following code segment produces the error?", + "options": { + "a": "'var_2 = var_1 * var'\nThis line produces the error because func_2() was not called and assigning the value to var_1, thus var_1 was referenced before being defined.", + "b": "'var_1 = var * 2'\nThis line produces the error because Python is confused about which value var should have.", + "c": "'def func_2(var):'\nThis line produces the error because the name var is already used for the argument of func_1() and cannot be used again as the name of the argument for func_2().", + "d": "'return var_2'\nThis line produces the error because one function cannot return two outputs." + }, + "correct": "a", + "explanation": "The inner function func_2 is defined but never called, so var_1 is never assigned before the line var_2 = var_1 * var tries to use it.", + "code_context": "def func_1(var):\n def func_2(var):\n var_1 = var * 2\n return var_1\n var_2 = var_1 * var\n return var_2", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 3, + "topic": "1_Basics_Variables_1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[str, int, NoneType, bool, float, str, dict]", + "b": "[str, int, NoneType, bool, float, bool, dict]", + "c": "[str, int, NoneType, bool, float, str, list]", + "d": "[str, float, NoneType, bool, int, str, dict]" + }, + "correct": "a", + "explanation": "The function appends the type of each element in the input list in order: string, integer, NoneType, boolean, float, string, and dictionary.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n list_2.append(type(item))\n return list_2\n\nmain(['abc', 0, None, True, 123.456, 'False', {}])", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 4, + "topic": "2-dictionaries - comprehension - 1", + "question": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\n\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97", + "options": { + "a": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou'}", + "b": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou' if vowel in 'aeiou'}", + "c": "Both of the code segments work correctly.", + "d": "Neither of the code segments work correctly." + }, + "correct": "c", + "explanation": "Both comprehensions produce the same dictionary because the extra condition in option B is always true for characters drawn from 'aeiou'.", + "code_context": "print(vowels_ASCII)\n# expected: {'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-04.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 5, + "topic": "2-dictionaries - manipulation - 1", + "question": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = (goals1, goals2, goals3)", + "b": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = [goals1 + goals2 + goals3]", + "c": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = [goals1, goals2, goals3]", + "d": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = (goals1, goals2, goals3)" + }, + "correct": "a", + "explanation": "Option A uses enumerate with start=1 to create the correct match-number keys and stores each triple of goal counts as a tuple. The other options either use the wrong value shape or start indexing from 0.", + "code_context": "player1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\nprint(match_goals)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Options C and D are small in the rendered page and should be human-confirmed if exact bracket style matters." + ] + } + }, + { + "number": 6, + "topic": "2-dictionaries - slicing - 1", + "question": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?", + "options": { + "a": "sales_subset = [monthly_sales[key] for key in list(monthly_sales.keys())[:3]]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "b": "sales_subset = monthly_sales[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "c": "sales_subset = list(monthly_sales.items())[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "d": "sales_subset = monthly_sales['January':'March']\naverage_sales = sum(sales_subset.values()) / len(sales_subset)\nprint(average_sales)" + }, + "correct": "a", + "explanation": "Option A first collects the values for the first three keys into a list and then computes the average correctly. The other options attempt unsupported dictionary slicing or try to sum tuples instead of numeric values.", + "code_context": "monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json new file mode 100644 index 0000000..11dc5e2 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q07-q12.json @@ -0,0 +1,156 @@ +{ + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_updates": [ + { + "number": 7, + "topic": "2-list - comprehension - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "[1, 4, 3, 8, 5]", + "b": "[2, 4, 6, 8, 10]", + "c": "[1, 2, 3, 4, 5]", + "d": "[2, 2, 6, 4, 10]" + }, + "correct": "a", + "explanation": "The list comprehension doubles only the even numbers and leaves the odd numbers unchanged, so the result is [1, 4, 3, 8, 5].", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x * 2 if x % 2 == 0 else x for x in numbers]\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 8, + "topic": "2-list - manipulation - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "['10a', '30c']", + "b": "[10, 20, 30, 40]", + "c": "['a', 'b', 'c', 'd']", + "d": "['10a', '20b', '30c', '40d']" + }, + "correct": "a", + "explanation": "The loop keeps only even indices from enumerate(list1), so it uses indices 0 and 2 and appends the concatenated strings '10a' and '30c'.", + "code_context": "list1 = [10, 20, 30, 40]\nlist2 = ['a', 'b', 'c', 'd']\n\nresult = []\n\nfor index, value in enumerate(list1):\n if index % 2 == 0:\n result.append(str(value) + list2[index])\n\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 9, + "topic": "2-list - slicing - 2", + "question": "Suppose you have a list called mylist. You want to extract every third element starting from index 1 (inclusive) to the last index (inclusive) from that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\n\nthen executing the following command:\nprint(subset)\n\nshould return:\n[15, 30, 45]\n\nWhat should the blanks be filled with?", + "options": { + "a": "1:len(mylist):3", + "b": "0:len(mylist):3", + "c": "1:len(mylist)-1:3", + "d": "0:len(mylist)-1:3" + }, + "correct": "a", + "explanation": "Starting at index 1 and stepping by 3 gives positions 1, 4, and 7, which are 15, 30, and 45. Using len(mylist) as the stop value includes the last valid stepped element.", + "code_context": "subset = mylist[___:___:___]\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\nprint(subset)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 10, + "topic": "3_Function_Argument_1", + "question": "Suppose you have the following function:\n\nWhat will be printed by the following line of code?\nprint(main())", + "options": { + "a": "True", + "b": "False", + "c": "0", + "d": "None" + }, + "correct": "d", + "explanation": "The default value of x is 0, so neither if-condition runs and the function reaches the end without returning anything, which prints None.", + "code_context": "def main(x = 0):\n if x > 0:\n return True\n\n if x < 0:\n return False\n\nprint(main())", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 11, + "topic": "3_Function_Built-in_3", + "question": "Suppose you have a variable called x which contains a list of integers as follows:\nx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nWhich of the following lines will produce an output that is different from the rest?", + "options": { + "a": "print(len(x))", + "b": "print(sorted(x, reverse=True)[0])", + "c": "print(x.index(9))", + "d": "print(sum(x[4:6]))" + }, + "correct": "a", + "explanation": "len(x) is 10, while sorted(x, reverse=True)[0] is 9, x.index(9) is 9, and sum(x[4:6]) is 4 + 5 = 9.", + "code_context": "x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 12, + "topic": "3_Function_Flexible-Argument_1", + "question": "You want to write a function called main which accepts a flexible number of integers as arguments.\n\nThe function should return a dictionary with the following key-value pairs:\n- key 'sum' has a value which is the sum of all the integers passed as arguments\n- key 'pro' has a value which is the multiplicative product of all the integers passed as arguments\n- key 'pow' has a value which is a list of all the squares of the integers passed as arguments\n\nWhich of the following lines of code will complete the function to give what you need?", + "options": { + "a": "x['sum'] = sum(args)\nx['pro'] = 1\nx['pow'] = []\nfor i in args:\n x['pro'] *= i\n x['pow'].append(i**2)", + "b": "x['sum'] = sum(args)\nx['pro'] = i for i in args\nx['pow'] = [i**2 for i in args]", + "c": "for i in args:\n x['sum'] = sum(args)\n x['pro'] *= i\n x['pow'] = [i**2 for i in args]", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "Option A correctly stores the sum, initializes the product accumulator to 1 before multiplying through the arguments, and builds the list of squares for each integer.", + "code_context": "def main(*args):\n x = {}\n\n # missing lines\n # ...\n\n return x", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option text for question 12, especially options B and C, is small in the rendered page and should be human-confirmed." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json new file mode 100644 index 0000000..6a93634 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q13-q18.json @@ -0,0 +1,157 @@ +{ + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_updates": [ + { + "number": 13, + "topic": "6-string - fstring - 2", + "question": "You have the following objects loaded in Python:\nitem = \"laptop\"\nprice = 1299.99\n\nYou need to print the following sentence:\nThe laptop is priced at $1299.99.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(message)", + "b": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(mesage)", + "c": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)", + "d": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)" + }, + "correct": "a", + "explanation": "Option A correctly uses positional placeholders and prints the defined variable `message`. Option B appears to use a misspelled variable name in the print call, and C/D mix named placeholders with positional arguments.", + "code_context": "item = \"laptop\"\nprice = 1299.99", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option B's printed variable name appears to be `mesage` in the rendered page and should be human-confirmed." + ] + } + }, + { + "number": 14, + "topic": "7-pandas - easy - 1", + "question": "Suppose you have run the following block of code:\n\nimport pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)\n\nWhich of the following lines of code give(s) the following output?\n1 4\n2 5\n3 6\nName: B, dtype: int64", + "options": { + "a": "df.loc[:, 'B']", + "b": "df['B'].loc[:]", + "c": "df['B']", + "d": "All of the given lines." + }, + "correct": "d", + "explanation": "Each of A, B, and C selects the same Series containing column `B`, so the correct choice is that all listed lines produce the shown output.", + "code_context": "import pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 15, + "topic": "8_Datetime_Easy_1", + "question": "Which code segment gives the same output as the following?\n\ndate = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))\n\nYou may assume that datetime and timedelta classess are already imported from the datetime module.", + "options": { + "a": "print(datetime.strptime('22-05-2023', '%d.%m.%Y'))", + "b": "print('02-05-2023')", + "c": "print(datetime.strptime('05.22.2023', '%d-%m-%Y'))", + "d": "date = datetime.strptime('10/05/2023', '%d/%m/%Y')\nprint((date + timedelta(days=5)).strftime('%m-%d-%Y'))" + }, + "correct": "b", + "explanation": "The original code parses May 12, 2023 and subtracts 10 days, so the printed result is the string `02-05-2023`.", + "code_context": "date = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 16, + "topic": "9_OOP_Easy_3", + "question": "You have the following definition for a class called Shape:\n\nWhat would be the output if we execute the following commands?\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "options": { + "a": "True", + "b": "False", + "c": "An error", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "`Shape(5, 3).area` is `5 * 3 = 15`, and `Shape(1, 15).length` is `15`, so the comparison evaluates to `True`.", + "code_context": "class Shape:\n def __init__(self, height, length):\n self.height = height\n self.length = length\n self.area = self.height * self.length\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 17, + "topic": "6-string - operations - 2", + "question": "Write a function called shuffle_sentence that takes a string as an argument and returns a new string where the words are shuffled randomly.\n\nFor example, if your function is called as:\nshuffle_sentence(\"Hello, how are you today?\")\nthen it could return a shuffled string like:\n'how today? you Hello, are'\n\nWhich of the following programs work(s) according to the requirements?\n\nHints:\nThe shuffle() function is a method from the random module. The shuffle() method takes a sequence, like a list, and reorganizes the order of the items. This method changes the original list; it does not return a new list.\nThe reversed() function computes the reverse of a given sequence object and returns it in the form of a list.", + "options": { + "a": "def shuffle_sentence(sentence):\n words = sentence.split()\n return ' '.join(reversed(words))", + "b": "import random\n\ndef shuffle_sentence(sentence):\n words = sentence.split()\n random.shuffle(words)\n return ' '.join(words)", + "c": "Both of the programs work.", + "d": "Neither of the programs work." + }, + "correct": "b", + "explanation": "Option B is the only one that actually shuffles the words randomly. Option A only reverses the word order, which does not satisfy the random-shuffle requirement.", + "code_context": "shuffle_sentence(\"Hello, how are you today?\")\n# could return: 'how today? you Hello, are'", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 18, + "topic": "6-strings - find & replace - 1", + "question": "Consider the following line of code:\n\ntext = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\n\nYou want to create a new string called new_text where all occurances of \"oil\" are replaced by \"natural gas\".\n\nSo:\nprint(new_text)\nshould return:\n\"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "new_text = ' '.join([word if word != 'oil' else 'natural gas' for word in text.split()])", + "b": "new_text = text.replace(\"oil\", \"natural gas\")", + "c": "new_text = text.split()\nfor index, word in enumerate(new_text):\n if word == 'oil':\n new_text[index] = 'natural gas'\nnew_text = ' '.join(new_text)", + "d": "All of the given options works as intended." + }, + "correct": "d", + "explanation": "All three code fragments replace each occurrence of the standalone word `oil` with `natural gas`, so the correct answer is that all of them achieve the requested result.", + "code_context": "text = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\nprint(new_text)\n# should return:\n# \"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The source image uses the misspelling `occurances`; that spelling was preserved from the rendered page." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json new file mode 100644 index 0000000..def60bc --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q19-q21.json @@ -0,0 +1,81 @@ +{ + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_updates": [ + { + "number": 19, + "topic": "7-pandas - hard - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Select all rows where the age is greater than 30 and the gender is \"Male\".\n- Operation 2: Create a new column called Sex_abbr of which the values should be \"F\" if gender is \"Female\" and \"M\" if gender is \"Male\".\n- Operation 3: Calculate the average salary of all employees.\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df_operation1 = df[(df['Age'] > 30) & (df['Gender'] == 'Male')]\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "b": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "c": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = df['Gender'].map(lambda x: 'M' if x == 'Male' else 'F')\ndf_operation3 = df['Salary'].sum()/len(df)", + "d": "df_operation1 = df[df['Age'] > 30 & df['Gender'] == 'Male']\ndf['Sex_abbr'].map(lambda x: 'M' if x == 'Male' else 'F' for x in df['Gender'])\ndf_operation3 = df['Salary'].sum()/len(df)" + }, + "correct": "a", + "explanation": "Option A correctly filters rows with both conditions using boolean masking, builds the abbreviation column from the Gender column, and computes the average salary with mean().", + "code_context": "Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some punctuation in the non-selected option code snippets is small in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "number": 20, + "topic": "7-pandas - lambda - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000\n\nYou want to create a new column called Bonus that compute each employee's bonus based on their salary and performance review using the following formula:\n- if the performance review is less than 4, the bonus is 0.\n- if the performance review is 4 or 5, the bonus is 5% of the salary.\n\nWhich of the following code snippets works as intended?", + "options": { + "a": "df['Bonus'] = df.apply(lambda row: row['Salary']*0.05 if row['Performance_review']>=4 else 0, axis=1)", + "b": "df['Bonus'] = df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>=4 else 0)", + "c": "df['Bonus'] = map(df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>4 else 0))", + "d": "df['Bonus'] = df['Salary'].map(lambda row: row*0.05 if df['Performance_review']>=4 else 0)" + }, + "correct": "a", + "explanation": "Option A evaluates each row, checks the row's Performance_review value, and returns either 5% of Salary or 0 for that employee.", + "code_context": "Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 21, + "topic": "8_Datetime_Function_3", + "question": "You want to create a function called main which take an integer and a flexible number of strings as arguments. The strings represent dates in the format of DD MM YYYY. The day, month and year can be separated by different characters.\n\nYour function should look for the string inputs which represent dates as DD-MM-YYYY or DD/MM/YYYY and return those strings in the format of DD.MM.YYYY in a list. Furthermore, the dates represented by the strings should be shifted by the amount of days as given by the integer argument.\n\nFor example, if we call your function as:\nmain(3, '25/06/2003', '26.06.2003', '27-06-2003', '28:06:2023', '29-06-2023', '30.06.2023')\n\nthe output should be:\n['28.06.2003', '30.06.2003', '02.07.2023']\n\nTake a look at the following code segment. Does it do what is intended? If not, then why not?", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the function will return a list of datetime objects, not a list of strings representing dates.", + "c": "This code segment does not work because the strftime() method cannot be applied to NoneType object.", + "d": "This code segment produces an error because you cannot concatenate strings and timedelta." + }, + "correct": "b", + "explanation": "The function parses matching inputs and adds the day offset, but it appends datetime objects and never converts them back to strings in DD.MM.YYYY format before returning.", + "code_context": "def main(delta, *args):\n dates = []\n for string in args:\n if '-' in string:\n dates.append(datetime.strptime(string, '%d-%m-%Y') + timedelta(days=delta))\n elif '/' in string:\n dates.append(datetime.strptime(string, '%d/%m/%Y') + timedelta(days=delta))\n else:\n dates.append(None)\n return [date for date in dates if type(date) != None]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q22-q24.json b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q22-q24.json new file mode 100644 index 0000000..4ffce92 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/final-exam-study-guide-trial-python-basics-2023-q22-q24.json @@ -0,0 +1,82 @@ +{ + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_updates": [ + { + "number": 22, + "topic": "8_Datetime_Hard_2", + "question": "You want to define a class called Calendar, which has four attributes that are initialized at the time of object construction:\n1. The 'event' attribute can be any string,\n2. The 'date' attribute is a string representing a date as 'DD-MM-YYYY',\n3. The 'start' attribute is a string representing the time as 'HH:MM', and\n4. The 'length' attribute is an integer representing the amount of minutes.\n\nThe class should also have a method called get_details() that gives a description of Calendar objects.\n\nFor example, if we execute the following commands;\nevent1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n\nthe output should be:\nCoffee meeting: 01-06-2023, 9:30-9:50.\n\nWhich of the following code segments gives you what you want?", + "options": { + "a": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day, int(start.split(':')[0]), int(start.split(':')[1]))\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "b": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.split(':')[0], minute=start.split(':')[1])\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "c": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.hour, minute=start.minute)\n self.end = self.self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "d": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start.hour = start.hour\n self.start.minute = start.minute\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'" + }, + "correct": "a", + "explanation": "Option A is the only choice that correctly parses the date string, combines the parsed date with the split start time to build a datetime, adds the duration in minutes, and formats the requested details string.", + "code_context": "event1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n# output:\n# Coffee meeting: 01-06-2023, 9:30-9:50.", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some small format-code and punctuation characters in the non-selected option snippets are hard to read in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "number": 23, + "topic": "9_OOP_Function_2", + "question": "You have the following definition for a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nYou want to add three methods to this class:\n1. The holiday_bonus() method which computes and returns the holiday bonus, which is 8.0% of the yearly salary,\n2. The year_end_bonus() method which computes and returns the year end bonus, which is 8.3% of the yearly salary\n3. The payment_overview() method which returns a payment overview of the employee using the following format:\n[Name] receives $[salary] monthly, $[holiday bonus] in May and $[year end bonus] in December.\n\nFor example, if we execute the following commands:\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())\n\nthe output should be:\n2400.0\n2490.0\nJohn Smith receives $2500 monthly, $2400.0 in May and $2490.0 in December.\n\nWhich of the following code segments should you place on the blank in the class definition to achieve what you want?", + "options": { + "a": "def holiday_bonus(self):\n return self.salary * 12 * 0.080\ndef year_end_bonus(self):\n return self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus()} in May and ${self.year_end_bonus()} in December.'", + "b": "def payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.salary*12*0.08} in May and ${self.salary*12*0.083} in December.'", + "c": "def holiday_bonus():\n self.holiday_bonus = self.salary * 12 * 0.080\ndef year_end_bonus():\n self.year_end_bonus = self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'", + "d": "def payment_overview(self):\n self.holiday_bonus = self.salary * 12 * 0.080\n self.year_end_bonus = self.salary * 12 * 0.083\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'" + }, + "correct": "a", + "explanation": "Option A defines all three requested methods, computes the two bonuses from the yearly salary, and uses those method results in the overview string.", + "code_context": "class Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 24, + "topic": "9_OOP_Hard_2", + "question": "You have the following definitions for a class called Car:\n\nclass Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nYou want to create another class called Garage, which has two attributes that are initialized during object construction:\n- The 'capacity' attribute, which is an integer and must be passed to the object constructor.\n- The 'cars' attribute, which is an empty list.\n\nThe Garage class should also have two methods:\n1. The add_car() method, which adds Car objects to a Garage object. New Car objects can only be added if there is still capacity in the Garage object. If not, the method should return \"Capacity reached.\"\n2. The check_garage() method, which reports the Car objects that have been added to the Garage object. The method should return a dictionary in which the keys are the counts of Car objects starting from 1 and the values are the Car objects' descriptions.\n\nFor example, if we execute the following commands:\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n\nthe output should be:\n{1: 'Toyota, Camry', 2: 'Honda, Accord'}\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "class Garage:\n def __init__(self, capacity, cars = []):\n self.capacity = capacity\n\n def add_car(self, car):\n self.cars += car if len(self.cars) < self.capacity else return 'Capacity reached.'\n\n def check_garage(self, car):\n return {index: car.get_description() for index, car in enumerate(self.cars, start=1)}", + "b": "class Garage:\n def __init__(self, capacity):\n self.capacity = capacity\n self.cars = []\n\n def add_car(self, car):\n if len(self.cars) < self.capacity:\n self.cars.append(car)\n else:\n return 'Capacity reached.'\n\n def check_garage(self):\n output = {}\n for index, car in enumerate(self.cars, start=1):\n output[index] = car.get_description()\n return output", + "c": "Both of the above will work.", + "d": "None of the above will work." + }, + "correct": "b", + "explanation": "Option B initializes capacity and an empty cars list, appends cars only when capacity remains, returns the required message when full, and builds the requested dictionary in check_garage().", + "code_context": "class Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n# output:\n# {1: 'Toyota, Camry', 2: 'Honda, Accord'}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some punctuation in non-selected option A is small in the rendered PNG and should be human-confirmed." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json new file mode 100644 index 0000000..f0373f1 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q01-q07-legacy-reverified.json @@ -0,0 +1,187 @@ +{ + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_updates": [ + { + "number": 1, + "topic": "1_Basics_Logic_3", + "question": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?", + "options": { + "a": "if x in list(range(11))[::2]:\n print('Even number')\nelse:\n print('Odd number')", + "b": "if x % 2 != 0:\n print('Odd number')\nelse:\n print('Even number')", + "c": "if x in [1, 3, 5, 7, 9]:\n print('Odd number')\nelse:\n print('Even number')", + "d": "All of the programs work as intended." + }, + "correct": "d", + "explanation": "Option A checks membership in the even numbers from 0 through 10, option B checks oddness with modulo, and option C checks membership in the odd numbers from 1 through 9. All three correctly classify x as odd or even in the stated range.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-02.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 2, + "topic": "1_Basics_Scope_2", + "question": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "options": { + "a": "This code will produce an error because a is a global name that is referenced inside the local scope of inner().", + "b": "This code will not produce any error and will return 30.", + "c": "This code will produce an error because c is not defined before referencing.", + "d": "This code will not produce any error and will return 50." + }, + "correct": "b", + "explanation": "The function inner receives c as its argument, so c is defined. It can also read the global a. inner(5) returns 1 + 5 + 4 = 10, and outer returns 10 * 3 = 30.", + "code_context": "a = 1\ndef outer(b):\n b = 3\n def inner(c):\n d = 4\n return a + c + d\n return inner(5) * b\nouter(5)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-02.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 3, + "topic": "1_Basics_Variables_2", + "question": "What will be returned by the following code segment?", + "options": { + "a": "[0, None, 2, 3, None, 5, 6, 7, 8, None]", + "b": "[0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, 9]", + "c": "[None, 1.0, None, None, 3.5, None, None, None, None, '9']", + "d": "[0, None, 2, 3, None, 5, 6, 7, 8, 9]" + }, + "correct": "a", + "explanation": "The function appends each item if its exact type is int; otherwise it appends None. In the given list, 1.0, 3.50, and '9' are not ints, so those positions become None.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n if type(item) == int:\n list_2.append(item)\n else:\n list_2.append(None)\n return list_2\n\nmain([0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, '9'])", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-03.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 4, + "topic": "2-dictionaries - comprehension - 2", + "question": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}", + "b": "roman_nums = {roman: num for roman, num in zip(['I', 'II', 'III', 'IV', 'V'], range(1, 6))}", + "c": "roman_nums = {num: ['I', 'II', 'III', 'IV', 'V'][num] for num in range(1, 6)}", + "d": "roman_nums = {num: roman for num, roman in zip(range(1, 6), 'I II III IV V')}" + }, + "correct": "a", + "explanation": "Option A zips the integers 1 through 5 with the five Roman numeral strings and builds the required dictionary. The other options either reverse the keys and values, use incorrect indexing, or iterate over a plain string instead of the intended list of numerals.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-03.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 5, + "topic": "2-dictionaries - manipulation - 2", + "question": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to only include the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[name] = age", + "b": "person_dict = {}\nfor i, name in enumerate(names):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[i] = ages[i]", + "c": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict.append(name:age)", + "d": "person_dict = {}\nfor i, name in enumerate(names):\n for j, letter in enumerate(name):\n if letter == 'A' or letter == 'C':\n person_dict[i] = ages[j]" + }, + "correct": "a", + "explanation": "Option A correctly iterates over names and ages together and stores only the names beginning with A or C as keys mapped to their ages. The other options use indices as keys, invalid dictionary syntax, or incorrect nested-loop logic.", + "code_context": "names = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 6, + "topic": "2-dictionaries - slicing - 2", + "question": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?", + "options": { + "a": "max_rating = max(employee_ratings.values())\nfor employee, rating in employee_ratings.items():\n if rating == max_rating:\n print(employee)", + "b": "max_rating_employee = max(employee_ratings.keys())\nfor employee, rating in employee_ratings.items():\n if employee == max_rating_employee:\n print(employee)", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "a", + "explanation": "Option A correctly computes the maximum rating value and prints every employee whose rating matches it. Option B instead finds the maximum key lexicographically, not the employee with the highest rating.", + "code_context": "employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 7, + "topic": "2-list - comprehension - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[2, 4]", + "b": "[3, 4, 5]", + "c": "[4]", + "d": "[]" + }, + "correct": "c", + "explanation": "The list comprehension keeps values x from [1, 2, 3, 4, 5] only when x is even and greater than 2. The only value satisfying both conditions is 4.", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x for x in numbers if x % 2 == 0 and x > 2]\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json b/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json new file mode 100644 index 0000000..b19ff49 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q08-q15.json @@ -0,0 +1,214 @@ +{ + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_updates": [ + { + "number": 8, + "topic": "2-list - manipulation - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "['a', 'bb', 'ccc']", + "b": "[1, 2, 3]", + "c": "[1, 'b', 3]", + "d": "['aa', 'bb', 'cc']" + }, + "correct": "a", + "explanation": "The loop iterates over pairs from zip(list1, list2) and multiplies each string by its matching integer, producing 'a', 'bb', and 'ccc'.", + "code_context": "list1 = [1, 2, 3]\nlist2 = ['a', 'b', 'c']\nresult = []\nfor item in zip(list1, list2):\n result.append(item[0] * item[1])\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "number": 9, + "topic": "2-list - slicing - 1", + "question": "Suppose you have a list called mylist. You want to extract every fourth element starting from index 2 (inclusive) to the second-to-last index (inclusive) of that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45, 50]\n\nthen executing the following command:\nprint(subset)\n\nshould print:\n[20, 35]\n\nWhat should the blanks be filled with?", + "options": { + "a": "2:-1:3", + "b": "2:len(mylist)-1:3", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "c", + "explanation": "Both stop values exclude the last element while starting at index 2 and stepping by 3, so both expressions return [20, 35] for the example list.", + "code_context": "subset = mylist[___:___:___]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "number": 10, + "topic": "3_Function_Argument_2", + "question": "Suppose you have the following function, which takes a list of integers as an argument:\n\nWhat will be returned, if we call the function as follows:\nmain([0, 1, 2, 23, 24, 25])", + "options": { + "a": "'abcxyz'", + "b": "['a', 'b', 'c', 'x', 'y', 'z']", + "c": "'012232425'", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "The function walks through the alphabet with enumerate and appends each character whose index is present in the input list, giving a, b, c, x, y, and z.", + "code_context": "def main(x):\n alphabet = 'abcdefghijklmnopqrstuvwxyz'\n y = ''\n for index, character in enumerate(alphabet):\n if index in x:\n y += character\n return y", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "number": 11, + "topic": "3_Function_Built-in_1", + "question": "Suppose you have a variable called x which contains a string as follows:\n\nx = 'Hello world'\n\nWhich of the following lines of code produce(s) 2 as an output?", + "options": { + "a": "print(x.count('o'))", + "b": "print(x.split(' ')[0].count('ll'))", + "c": "print(len(x)//5)", + "d": "All of the given options." + }, + "correct": "d", + "explanation": "The rendered solution page marks option D, indicating that the exam intends all three listed expressions to produce 2 for the given value of x.", + "code_context": "x = 'Hello world'", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page.", + "Option B's inner string literal is small in the source image and should be human-confirmed during merge review." + ] + } + }, + { + "number": 12, + "topic": "3_Function_Flexible-Argument_2", + "question": "You need to write a function called main which accepts a list of integers as an argument. The function should return a tuple of two integers, in which the first is the sum of the squares of all even numbers, and the second is the sum of the squares of all odd numbers.\n\nFor example, calling the function as:\nmain(1, 2, 3, 4)\nshould return:\n(20, 10)\n\nWhich of the following blocks of code fits with the rest of the program and will you give the intended output?", + "options": { + "a": "for i in args:\n if i % 2 == 0:\n total_even += i**2\n else:\n total_odd += i**2\n\nreturn (total_even, total_odd)", + "b": "for i in args:\n if i % 2 == 1:\n total_even += i\n else:\n total_odd += i\n\nreturn (total_even**2, total_odd**2)", + "c": "for i in args:\n if i % 2 == 0:\n total_even.append(i**2)\n else:\n total_odd.append(i**2)\n\nreturn (sum(total_even), sum(total_odd))", + "d": "All of the given code blocks work as intended." + }, + "correct": "a", + "explanation": "Option A directly accumulates the squares of even numbers and odd numbers into the two totals and returns them as the required tuple.", + "code_context": "def main(*args):\n total_even = 0\n total_odd = 0\n\n # missing lines\n # ...", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "number": 13, + "topic": "6-string - fstring - 1", + "question": "You have the following objects loaded in Python:\nname = \"Alice\"\nage = 25\ncountry = \"the USA\"\n\nYou need to print the following string:\nMy name is Alice. I am 25 years old, and I am from the USA.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"My name is {0}. I am {2} years old, and I am from {1}.\".format(name, country, age)\nprint(message)", + "b": "message = f\"My name is {name}. I am {age} years old, and I am from {country}.\"\nprint(message)", + "c": "message = 'My name is ' + name + '. I am ' + str(age) + ' years old, and I am from ' + str(country) + '.'\nprint(message)", + "d": "All of the given options are correct." + }, + "correct": "d", + "explanation": "All three code variants produce the target sentence: one uses format, one uses an f-string, and one uses string concatenation with str(age) and str(country).", + "code_context": "name = \"Alice\"\nage = 25\ncountry = \"the USA\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "number": 14, + "topic": "7-pandas - easy - 2", + "question": "Suppose you have the following DataFrame called df, and assume that pandas is already imported:\n\n Player Goals Assists\n0 John 5 2\n1 Jane 3 6\n2 Alex 2 4\n\nAll of the following lines of code make the same selection, but one of the results has a different datatype. Which one?", + "options": { + "a": "df.loc[:, 'Goals']", + "b": "df['Goals']", + "c": "df.loc[[0, 1, 2], 'Goals']", + "d": "df.loc[:, ['Goals']]" + }, + "correct": "d", + "explanation": "The first three expressions return a Series, while selecting with a list of column names returns a one-column DataFrame instead.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + }, + { + "number": 15, + "topic": "8_Datetime_Easy_3", + "question": "Which code segment gives the same output as the following:\n\ndate1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module.", + "options": { + "a": "print((datetime(2023, 5, 1) - datetime(2023, 6, 1)).days)", + "b": "print((datetime(2023, 6, 1) - datetime(2023, 1, 5)).days)", + "c": "print((datetime.strptime('2023-6-1', '%Y-%d-%m') - datetime.strptime('2023-5-1', '%Y-%d-%m')).days)", + "d": "print((datetime.strptime('2023-06-01', '%Y-%m-%d') - datetime.strptime('2023-05-01', '%Y-%m-%d')).days)" + }, + "correct": "d", + "explanation": "Option D parses ISO-style date strings using the matching '%Y-%m-%d' format and subtracts the May date from the June date, giving the same day difference as the original code.", + "code_context": "date1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Correct answer identified from the shaded answer marker on the rendered solution page." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json b/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json new file mode 100644 index 0000000..dd6e77a --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/introduction-to-python-trial-final-exam-solutions-py22-q16-q24.json @@ -0,0 +1,230 @@ +{ + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_updates": [ + { + "number": 16, + "topic": "9_OOP_Easy_2", + "question": "You have the following definition of a class called Flight. What would be the output if we execute the following statements?", + "options": { + "a": "'long'\n'cheap'", + "b": "'short'\n'expensive'", + "c": "'long'\n'expensive'", + "d": "'short'\n'cheap'" + }, + "correct": "a", + "explanation": "The first condition sets the KLM flight to Singapore to duration 'long', and the second condition sets the EasyJet flight to Spain to price 'cheap', so the two prints output 'long' and then 'cheap'.", + "code_context": "class Flight:\n def __init__(self, airline, destination):\n self.airline = airline\n self.destination = destination\n\n if self.airline == 'KLM' and self.destination == 'Singapore':\n self.duration = 'long'\n self.price = 'expensive'\n\n if self.airline == 'EasyJet' and self.destination == 'Spain':\n self.duration = 'short'\n self.price = 'cheap'\n\nprint(Flight('KLM', 'Singapore').duration)\nprint(Flight('EasyJet', 'Spain').price)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 17, + "topic": "6-string - operations - 1", + "question": "Consider the following code snippet. Which operation in the code snippet contains an error?", + "options": { + "a": "Operation 1", + "b": "Operation 2", + "c": "Operation 3", + "d": "None of the operations contains an error." + }, + "correct": "b", + "explanation": "Operation 2 is incorrect because join should be called as the separator string's method with a single iterable argument, for example '-'.join(word_list).", + "code_context": "text = \"The universe is vast and full of mysteries!\"\n\n# Operation 1:\nword_list = []\nfor word in text.split():\n word_list.append(word[::-1])\n\n# Operation 2:\njoined_text = ' '.join(word_list, '-')\n\n# Operation 3:\nreplaced_text = text.replace(\"mysteries\", \"secrets\")", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 18, + "topic": "6-strings - find - 2", + "question": "Suppose you have the following variables called sentence1 and sentence2 which contain strings. The sentences contain names, but they are not properly capitalized. You want to create a new string object called paragraph, with the proper nouns capitalized in the two sentences and the two sentences connected into one big string.\n\nThat is, if we execute the following line of code:\nprint(paragraph)\nthe output should be:\n\"Harry, Ron, and Hermione walked through the halls of Hogwarts; their footsteps echoing off the stone walls.\nThe Marauder's map in Harry's hands revealed the secret passageways and hidden rooms of the castle.\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor name in names:\n sentence1[sentence1.find(name)] = name.capitalize()\n sentence2[sentence2.find(name)] = name.capitalize()\nparagraph = sentence1 + \" \" + sentence2", + "b": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor word, name in zip(sentence1, names):\n if word == name:\n sentence1 = sentence1.replace(word, name.capitalize())\nfor word, name in zip(sentence2, names):\n if word == name:\n sentence2 = sentence2.replace(word, name.capitalize())\nparagraph = sentence1 + \" \" + sentence2", + "c": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nnew1 = ' '.join([word.capitalize() if word in names else word for word in sentence1])\nnew2 = ' '.join([word.capitalize() if word in names else word for word in sentence2])\nparagraph = new1 + \" \" + new2", + "d": "for word in ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']:\n sentence1 = sentence1.replace(word, word.capitalize())\n sentence2 = sentence2.replace(word, word.capitalize())\nparagraph = sentence1 + \" \" + sentence2" + }, + "correct": "d", + "explanation": "Option D correctly replaces each lowercase proper noun with its capitalized version in both strings and then concatenates the two sentences into paragraph.", + "code_context": "sentence1 = \"harry, ron, and hermione walked through the halls of hogwarts; their footsteps echoing off the stone walls.\"\nsentence2 = \"The marauder's map in harry's hands revealed the secret passageways and hidden rooms of the castle.\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 19, + "topic": "7-pandas - hard - 2", + "question": "Consider the following pandas DataFrame called df, and assume that Pandas is already imported.\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Name_Length that contains the length of each person's name\n- Operation 2: Replace all occurrences of the occupation 'Engineer' with 'Software Developer'\n- Operation 3: Extract the last two characters of each person's name and store them in a new column called Name_Suffix\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df['Name_Length'] = df['Name'].map(lambda x: len(x))\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:])", + "b": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].lambda x: x[-2:]", + "c": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[:-2])", + "d": "df['Name_Length'] = df['Name'].map(len)\ndf['Occupation'] = df['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:-1])" + }, + "correct": "a", + "explanation": "Option A correctly maps each name to its length, replaces only the Engineer entries, and slices the final two characters with x[-2:].", + "code_context": " Name Age Occupation\n0 John 25 Student\n1 Jane 30 Engineer\n2 Alex 35 Scientist\n3 Lisa 40 Doctor\n4 Mark 28 Architect", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 20, + "topic": "7-pandas - lambda - 2", + "question": "What will be printed by the following code?", + "options": { + "a": " Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 72 13\n1 B 45 19", + "b": " Product Units Price\n1 B 50 19\n0 A 100 10\n3 D 80 13\n2 C 200 15", + "c": " Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 80 13\n1 B 50 19", + "d": " Product Units Price\n2 C 200 15\n3 D 80 13\n0 A 100 10\n1 B 50 19" + }, + "correct": "c", + "explanation": "UnitsCorrected and Revenue are used only for sorting; df1 keeps the original Units and Price columns, and sorting by descending revenue gives rows C, A, D, B.", + "code_context": "import pandas as pd\nd = {'Product':['A', 'B', 'C', 'D'], 'Units':[100, 50, 200, 80], 'Price':[10, 19, 15, 13]}\ndf = pd.DataFrame(d)\ndf.loc[:, 'UnitsCorrected'] = df.loc[:, 'Units'].map(lambda x: 0.9*x if x < 100 else x)\ndf.loc[:, 'Revenue'] = df.loc[:, 'UnitsCorrected'] * df.loc[:, 'Price']\ndf = df.sort_values(by='Revenue', ascending=False)\ndf1 = df.loc[:, ['Product', 'Units', 'Price']]\nprint(df1)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 21, + "topic": "8_Datetime_Function_2", + "question": "You have the following definition for a class called Calendar.\n\nThe method check_overlap() should return True if there are two overlapping events and False if the two events are not overlapping.\n\nFor example, if we have the following Calendar objects:\nevent1 = Calendar('Coffee meeting', '01-06-2023 9:30', 20)\nevent2 = Calendar('Writing session', '01-06-2023 10:00', 150)\nevent3 = Calendar('Lunch meeting', '01-06-2023 12:00', 45)\n\nthe following command should return False:\nprint(event1.check_overlap(event2))\n\nand the following command returns True:\nprint(event2.check_overlap(event3))\n\nDoes the code segment given above do what you want? If not, then why not?\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the condition provided after the return keyword is incorrect.", + "c": "This code segment does not work because the syntax to parse the input string to create a datetime object is incorrect.", + "d": "This code segment does not work because the __init__ method needs 4 parameters and only 3 arguments are passed." + }, + "correct": "a", + "explanation": "The datetime format string matches the input values, timedelta(minutes=length) creates the correct end time, and the overlap condition correctly detects whether two intervals intersect.", + "code_context": "from datetime import datetime, timedelta\n\nclass Calendar():\n def __init__(self, event, start, length):\n self.event = event\n self.start = datetime.strptime(start, '%d-%m-%Y %H:%M')\n self.end = self.start + timedelta(minutes=length)\n def check_overlap(self, other):\n return self.start < other.end and self.end > other.start", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 22, + "topic": "8_Datetime_Hard_1", + "question": "You want to create a DataFrame called df that has the following format:\n\n Day Month Year\n01-01-23 1 1 2023\n08-01-23 8 1 2023\n15-01-23 15 1 2023\n22-01-23 22 1 2023\n29-01-23 29 1 2023\n\nWhich of the following code segments achieves what you want?\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module, as well as the pandas module (via: import pandas as pd).\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "dates = [(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=[date.strftime('%d-%m-%y') for date in dates])", + "b": "dates = [(datetime(2023, 1, 1) + timedelta(days=7*i)).strftime('%d-%m-%y') for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=dates)", + "c": "day = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).day for i in range(5)])\nmonth = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).month for i in range(5)])\nyear = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).year for i in range(5)])\ndf = pd.DataFrame(data=[day, month, year])", + "d": "df = pd.DataFrame(index=[(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)],\n {'Day': [date.days for date in index],\n 'Month': [date.months for date in index],\n 'Year': [date.year for date in index]})" + }, + "correct": "a", + "explanation": "Option A keeps real datetime objects long enough to derive day, month, year, and then formats those dates into the desired string index for the DataFrame.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 23, + "topic": "9_OOP_Function_3", + "question": "You have the following definition of a class called Pack.\n\nYou want to add to this class a method called fitting() that calculates how many times another object of the class Pack would fit inside this object.\nThe method should return the number of times these other objects would fit completely in this object, and the final value.\nThe final value is the sum of all values of all objects that fit in it, plus the value of the carrying object self.\n\nFor example, if we execute the lines of code:\nbackpack = Pack(size=15, value=20)\nbook = Pack(size=4, value=10)\nbackpack.fitting(book)\n\nthe output should be:\nAmount: 3. Value: 50.\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def fitting(self, other):\n if self.size > other.size:\n self.total = (self.size // other.size) * other.value + self.value\n return f'Amount: {self.size // other.size}. Value: {self.total}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "b": "def fitting(self, other):\n if self.size > other.size:\n return f'Amount: {self.size // other.size}. Value: {other.value * other.size}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "c": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return f'Amount: {self.amount}. Value: {self.total}.'", + "d": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return 'Amount: {}. Value: {}.'.format(self.amount, self.value if self.size > other.size else self.total)" + }, + "correct": "a", + "explanation": "Option A uses integer floor division to count only full fits, adds the carried items' value plus self.value, and returns zero items with self.value when the other object does not fit.", + "code_context": "class Pack:\n def __init__(self, size, value = 0):\n self.size = size\n self.value = value\n\n # missing lines\n # ...", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 24, + "topic": "9_OOP_Hard_1", + "question": "You have the following definition for a class called Piece.\n\nAnd the creation of three objects with the help of the class definition:\na = Piece(diagonal=True, straight=False, initial_position=(0, 0))\nb = Piece(diagonal=False, straight=True, initial_position=(4, 3))\nc = Piece(diagonal=True, straight=True, initial_position=(9, 6))\n\nIf we run the following statements:\nprint(a.check_move((4, 4)))\nprint(b.check_move((5, 5)))\nprint(c.check_move((6, 6)))\n\nThis will print 3 Boolean values. Of these values, how many times will this be True?", + "options": { + "a": "0", + "b": "1", + "c": "2", + "d": "3" + }, + "correct": "b", + "explanation": "The first move fails because the row and column differences are both 4, which is above the allowed maximum of 3. The second fails because a straight-only piece cannot move diagonally. The third succeeds because a piece that can move straight and diagonally may move along the same column within 3 steps, so exactly one result is True.", + "code_context": "class Piece:\n def __init__(self, diagonal, straight, initial_position):\n self.diagonal = diagonal\n self.straight = straight\n self.initial_position = initial_position\n\n def check_move(self, target_position):\n self.target_position = target_position\n self.row_diff = self.target_position[0] - self.initial_position[0]\n if abs(self.row_diff) > 3:\n return False\n self.col_diff = self.target_position[1] - self.initial_position[1]\n if abs(self.col_diff) > 3:\n return False\n\n if self.diagonal and (not self.straight):\n return abs(self.row_diff) == abs(self.col_diff)\n if self.straight and (not self.diagonal):\n return abs(self.row_diff) == 0 or abs(self.col_diff) == 0\n if self.straight and self.diagonal:\n return (abs(self.row_diff) == abs(self.col_diff)) or (abs(self.row_diff) == 0 or abs(self.col_diff) == 0)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-17.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json new file mode 100644 index 0000000..66f8798 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01-q03-legacy-reverified.json @@ -0,0 +1,81 @@ +{ + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_updates": [ + { + "number": 1, + "topic": "Multiple choice - Question-ID: 357615", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "All three expressions evaluate to True: 2 * 3 = 6 equals x[2][1], 3 + 5 = 8 equals x[-1][1], and 7 - 5 = 2 equals x[0][1].", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 2, + "topic": "Multiple choice - Question-ID: 357607", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "The function called power should not return the string 'The result of {} ** {} is: {}'.format(num, factor, result), but the value of result.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "Result is a local name that cannot be referenced outside of the function power." + }, + "correct": "d", + "explanation": "`result` is defined inside the function `power`, so it is local to that function. The statement `print(result)` outside the function therefore raises a name error because `result` is not defined there.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}'.format(num, factor, result)\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 3, + "topic": "Multiple choice - Question-ID: 355235", + "question": "What will be printed by the following code segment?", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[]", + "d": "[None]" + }, + "correct": "d", + "explanation": "The code appends list-typed elements to `y`, but the return expression uses `append`, which itself returns `None`. The page marks option D as correct, so the intended evaluated output is `[None]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n\n return [y.append(i)]\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Question 3 return line is small in the rendered PNG and should be human-confirmed during merge review." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json new file mode 100644 index 0000000..1c1fb68 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04-q06-legacy-reverified.json @@ -0,0 +1,80 @@ +{ + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_updates": [ + { + "number": 4, + "topic": "function defaults and loops", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "This code produces an error as there is a missing argument when calling main.", + "b": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10']", + "c": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')", + "d": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10',\n '1 * 11 = 11']" + }, + "correct": "b", + "explanation": "`main(1)` is valid because `y` has default value `11`. The loop starts at `i = 1` and runs while `i < y`, so it appends the multiplication strings for 1 through 10 and stops before 11.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nprint(main(1))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 5, + "topic": "list slicing and sets", + "question": "Suppose you have a list called x, where:\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Option A removes duplicates and sorts descending, which gives `[5, 4, 3, 2, 1]`. Option B takes every second element from the end of the symmetric list and also prints `[5, 4, 3, 2, 1]`.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n# target output:\n# [5, 4, 3, 2, 1]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 6, + "topic": "keyword arguments", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "To sum the numeric keyword-argument values, the function must iterate over `kwargs.values()`. Option A adds the string keys instead of the prices, and Option C incorrectly tries to unpack `kwargs.keys()`.", + "code_context": "main(apple=1.99, banana=0.99, orange=1.49)\n# should return 4.47", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json new file mode 100644 index 0000000..ce17f50 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07-q12.json @@ -0,0 +1,155 @@ +{ + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_updates": [ + { + "number": 7, + "topic": "Dictionaries and Mappings", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {word: len for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to the length of that word. The other options either reverse key/value order or use invalid logic.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 8, + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades.\n\nThe students list contains strings representing the names of students.\nThe grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears. B builds lists of students per grade instead of counting them.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 9, + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the right result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 10, + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 11, + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 12, + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json new file mode 100644 index 0000000..a742442 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13-q15.json @@ -0,0 +1,80 @@ +{ + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_updates": [ + { + "number": 13, + "topic": "Multiple choice", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", leaving only the second occurrence replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 14, + "topic": "Multiple choice", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the requested sentence exactly, including the word \"and\" before the final fruit. Option A joins the list as \"apple, banana, orange\" and does not produce the exact requested wording.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 15, + "topic": "Multiple choice", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})", + "b": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "c": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "d": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)" + }, + "correct": "d", + "explanation": "Option D constructs one aligned series for the local parts and one for the domains, then returns them in a DataFrame with the correct column names. The other options either overwrite values, build the wrong structure, or use the wrong field names.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json new file mode 100644 index 0000000..7482ff9 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16-q18.json @@ -0,0 +1,81 @@ +{ + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_updates": [ + { + "number": 16, + "topic": "Multiple choice", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "False\nTrue", + "c": "False\nFalse", + "d": "True\nFalse" + }, + "correct": "a", + "explanation": "The object is created with name 'John Smith', and because no gender argument is passed, the default value 'not specified' is used. Both comparisons therefore evaluate to True.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 17, + "topic": "Multiple choice", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original expression computes the number of days between January 10 and January 1, then adds 1, which yields 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option B contains a small formatting detail that should be human-confirmed from the page, but the marked correct answer is clearly D." + ] + } + }, + { + "number": 18, + "topic": "Multiple choice", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df[['Player', 'Age']])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df.loc[:, 'Age'])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing in this form does not accept the tuple (1, 'Age') to select a single cell.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json new file mode 100644 index 0000000..418226c --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19-q24.json @@ -0,0 +1,158 @@ +{ + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_updates": [ + { + "number": 19, + "topic": "animals methods", + "question": "You have the following definition for a class called Animals:\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs = True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin = True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "def walk():\n return sound if legs else 'Cannot walk!'\ndef swim():\n return sound if fin else 'Cannot swim!'", + "d": "def walk():\n if legs == True:\n return sound\n else:\n return 'Cannot walk!'\ndef swim():\n if fin == True:\n return sound\n else:\n return 'Cannot swim!'" + }, + "correct": "a", + "explanation": "Option A is the only choice that defines both instance methods with self and correctly returns self.sound when the corresponding boolean attribute is truthy, otherwise the required fallback string.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ...", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-11.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Question stem is on page-11.png and answer options continue on page-12.png." + ] + } + }, + { + "number": 20, + "topic": "movie review methods", + "question": "You have the following definition for a class named Movie.\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute,\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and return the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segments will work as intended." + }, + "correct": "d", + "explanation": "Option A is broken because add_review uses list-plus-number syntax and compare immediately returns on the first loop iteration, so it never returns other.title when the other movie has the higher rating. Option B is also broken because add_review and rating are missing self and compare compares method objects instead of calling them.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ...", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 21, + "topic": "datetime weekly dates list", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "b": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "c": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "d": "This code segment will work as intended." + }, + "correct": "c", + "explanation": "After the first append, the newly added element is a formatted string, so on the next loop iteration the code tries to add a timedelta to a string instead of to a datetime object.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 22, + "topic": "pandas date column from day month year", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A correctly constructs datetime objects in year-month-day order from the three columns and then formats them into the requested DD-MM-YYYY strings.", + "code_context": " Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 23, + "topic": "pandas above average salary", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 1000\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "None of the blocks of code will work as intended.", + "c": "Both blocks of code will work as intended.", + "d": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])" + }, + "correct": "a", + "explanation": "Option A correctly computes the mean salary, builds both required columns, and prints the full DataFrame filtered to rows where Above_average is True. Option D does not print the result in the required way because it filters only on Salary_difference > 0 rather than explicitly using the Above_average column requested in the specification.", + "code_context": " Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The printed output in option D would likely show the same rows, but option A more directly matches the stated required operations and final result." + ] + } + }, + { + "number": 24, + "topic": "pandas lambda output", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": " A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "b": " A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "c": " A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15", + "d": " A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18" + }, + "correct": "d", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing C values 16, 17, and 18.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-17.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json new file mode 100644 index 0000000..b4f9940 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q01-q04-legacy-reverified.json @@ -0,0 +1,109 @@ +{ + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_updates": [ + { + "number": 1, + "topic": "1_Basics_Logic_1", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "The three code lines evaluate to 2 * 3 == 6, 3 + 5 == 8, and 7 - 5 == 2, so each one is True. Therefore the correct choice is that all lines print True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The left option labels are partially obscured by the rendered page overlay, but the visible option texts and the selected outcome verify the answer." + ] + } + }, + { + "number": 2, + "topic": "1_Basics_Scope_1", + "question": "Executing the following program will produce an error. Why?\n\ndef power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)", + "options": { + "a": "Result is a local name that cannot be referenced outside of the function power.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "The function called power should not return the string 'The result of {} ** {} is: {}.'.format(num, factor, result), but the value of result." + }, + "correct": "a", + "explanation": "`result` is defined inside the function, so it has local scope. The line `print(result)` is outside the function and therefore cannot access that local variable.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The selected answer text is visible in bold on the rendered page; left-side option labels are partially obscured by the overlay." + ] + } + }, + { + "number": 3, + "topic": "1_Basics_Variables_3", + "question": "What will be printed by the following code segment?\n\ndef main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[None]", + "d": "[]" + }, + "correct": "b", + "explanation": "The function appends only elements whose type matches the type of `x`, which is `list`. Among the provided elements, only `[]` is itself a list, so the printed result is `[[]]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The right edge of the input list is slightly clipped in the rendered PNG, but the visible options and the function logic confirm the selected answer `[[]]`." + ] + } + }, + { + "number": 4, + "topic": "3_Function_Argument_3", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\ndef main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10']", + "b": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10', '1 * 11 = 11']", + "c": "This code produces an error as there is a missing argument when calling main.", + "d": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')" + }, + "correct": "a", + "explanation": "When `main(1)` is called, `y` uses its default value `11`. The loop runs for `i` values 1 through 10, so it returns a list of ten multiplication strings from `1 * 1 = 1` through `1 * 10 = 10`.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The left option labels are partially obscured by the overlay, but the visible answer texts and the selected outcome verify the correct option." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json new file mode 100644 index 0000000..656eed7 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q05-q07-legacy-reverified.json @@ -0,0 +1,80 @@ +{ + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_updates": [ + { + "number": 5, + "topic": "Functions Built-in", + "question": "Suppose you have a list called x, where:\n\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Both snippets produce [5, 4, 3, 2, 1]. The first removes duplicates and sorts the unique values in reverse order, and the second slices every second element from the reversed list.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-04.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 6, + "topic": "Function Flexible Argument", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "B sums the keyword argument values, which is exactly what the function should do. A incorrectly adds the keyword names, and C iterates over keys in a way that does not match the intended structure.", + "code_context": "def main(**kwargs):\n # Sum the values passed as keyword arguments", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-04.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 7, + "topic": "Dictionaries Comprehension", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {len: word for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to its length. The other options either reverse the key/value order or use invalid comprehension logic.", + "code_context": "words = ['example', 'python', 'exam']", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png" + ], + "notes": [ + "Legacy record re-verified from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json new file mode 100644 index 0000000..94e1650 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q08-q12.json @@ -0,0 +1,130 @@ +{ + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_updates": [ + { + "number": 8, + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades:\n- The students list contains strings representing the names of students.\n- The grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears, which matches the requested dictionary. B stores lists of students per grade, so it does not produce counts.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 9, + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the correct result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 10, + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 11, + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 12, + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json new file mode 100644 index 0000000..a20b575 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q13-q18.json @@ -0,0 +1,156 @@ +{ + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_updates": [ + { + "number": 13, + "topic": "string - find - 3", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", so only the second occurrence remains replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 14, + "topic": "string - fstring - 3", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the required sentence exactly, including the word \"and\" before the final fruit. Option A joins the list without \"and\", so it does not produce the exact requested output.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 15, + "topic": "string - operations - 3", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)", + "b": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "c": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "d": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})" + }, + "correct": "a", + "explanation": "Option A builds aligned pandas Series for the local parts and domains, then returns them in a DataFrame with the correct column names. The other options either swap fields, overwrite values, or construct the DataFrame incorrectly.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 16, + "topic": "6_OOP_Easy_1", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "True\nFalse", + "c": "False\nTrue", + "d": "False\nFalse" + }, + "correct": "a", + "explanation": "The name comparison is true because the object stores 'John Smith', and the gender comparison is also true because the default value 'not specified' is used when no gender is provided.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 17, + "topic": "8_Datetime_Easy_2", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original code computes the difference in days between January 10 and January 1, then adds 1, yielding 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-10.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option A/B formatting is small in the rendered page and should be human-confirmed if exact punctuation matters; the correct answer is still clear from the logic of the visible options." + ] + } + }, + { + "number": 18, + "topic": "pandas - easy - 3", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df.loc[:, 'Age'])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df[['Player', 'Age']])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing does not accept the tuple (1, 'Age') in this form.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json new file mode 100644 index 0000000..5ce4447 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/resit-solutions-for-introduction-to-python-35761538-q19-q24.json @@ -0,0 +1,159 @@ +{ + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_updates": [ + { + "number": 19, + "topic": "6_OOP_Function_1", + "question": "You have the following definition for a class called Animals:\n\nclass Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ...\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs == True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin == True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "c", + "explanation": "Both shown method implementations use the instance attributes to return the animal's sound when the relevant boolean attribute is present and the required fallback message otherwise.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The lower-left answer labels are partially obscured in the rendered PNG; option text and the selected outcome were reconstructed from the visible code blocks and question structure." + ] + } + }, + { + "number": 20, + "topic": "6_OOP_Hard_3", + "question": "You have the following definition for a class named Movie.\n\nclass Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ...\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute.\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and returns the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "d", + "explanation": "The first code segment is broken because it tries to add an integer directly to a list and its compare logic cannot return the other movie's title correctly. The second code segment omits self where needed and compares method objects instead of method results.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some punctuation in the non-selected code options is small in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "number": 21, + "topic": "8_Datetime_Function_1", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "b": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "c": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "d": "This code segment will work as intended." + }, + "correct": "b", + "explanation": "After the first append inside the loop, the list contains formatted date strings. On the next iteration the code tries to add a timedelta to that string, which is not allowed.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-14.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 22, + "topic": "8_Datetime_Hard_3", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas module is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A builds real datetime objects using year, month, and day in the correct order and then formats each one as DD-MM-YYYY.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-15.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Some small punctuation in the non-selected option snippets is hard to read in the rendered PNG and should be human-confirmed." + ] + } + }, + { + "number": 23, + "topic": "pandas - hard - 3", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 100\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])", + "c": "Both blocks of code will work as intended.", + "d": "None of the blocks of code will work as intended." + }, + "correct": "c", + "explanation": "Both code blocks compute the rounded mean salary, derive an above-average indicator, compute salary differences from that mean, and filter the rows with positive differences.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-16.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 24, + "topic": "pandas - lambda - 3", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": " A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18", + "b": " A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "c": " A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "d": " A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15" + }, + "correct": "a", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing 16, 17, and 18 in column C.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-17.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "The option-letter area is partially obscured in the rendered PNG, but the four visible output tables were transcribed from top to bottom as options a through d." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json new file mode 100644 index 0000000..d73b052 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q01-q08-legacy-reverified.json @@ -0,0 +1,207 @@ +{ + "exam_id": "sample-final-plus-answers", + "question_updates": [ + { + "number": 1, + "topic": "vehicle class defaults", + "question": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation.\nThe name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string \"land\".\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A correctly defines the constructor with `self`, stores both attributes on the instance, and gives `vehicle_mode` the default value `\"land\"`.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Question 1 option code is small in the rendered page and should be human-confirmed during merge review." + ] + } + }, + { + "number": 2, + "topic": "book rating output", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The stored review scores are 5, 3, and 3. Their average is 11 / 3 = 3.666..., and the method rounds that to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-05.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 3, + "topic": "student grade formatting", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\nFor example, if\nstudents = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 75.\nBernard has received a grade of 80.\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']}. \")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {student['Grade']}. \")", + "c": "for student in students:\n print(f\"{student['Name']} has received a grade of \" + str(student[\"Grade\"]))", + "d": "for student, grade in students.items():\n print(f'{student} has received a grade of {grade}.')" + }, + "correct": "a", + "explanation": "Option A iterates through the list of dictionaries and prints each student's name together with that student's grade. The other options incorrectly call `.items()` on the list or use the wrong data access pattern.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-07.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Question 3 option text should be human-confirmed for exact spacing/punctuation around the printed sentence." + ] + } + }, + { + "number": 4, + "topic": "phone number formatting", + "question": "You need to write a function called format_phone_number that formats phone numbers.\nThe output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) at various places.\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A calls `replace` but does not store its result, so it returns the original unchanged string. The other options all build and return the digits without the dashes.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# should all return \"0205251400\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-09.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 5, + "topic": "pandas even-row selection", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.9\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that looks like this, when printed:\n\n B\n2 8.2\n4 3.6\n6 8.4\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters the even-numbered row labels and keeps column `B` as a one-column DataFrame, matching the printed target. The other options use invalid indexing, select the wrong column/positions, or return a Series instead of the shown DataFrame.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-11.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 6, + "topic": "pandas df2 derivation", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False).loc[:, [\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A would keep all five rows after sorting the index descending, so it would not produce the shown three-row df2. The other options can all produce rows 4, 3, and 2 with columns A, C, and D in the displayed order.", + "code_context": "", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-13.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 7, + "topic": "datetime month parser", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "`\"03/02/2013\"` is parsed with `%m/%d/%Y`, so its month is 3. `\"03.02.2013\"` matches neither separator rule and becomes `None`. `\"03-02-2013\"` is parsed with `%d-%m-%Y`, so its month is 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-15.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 8, + "topic": "dictionary comprehension lengths", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the only dictionary comprehension that maps each string to its own length. Option B makes a list, Option C makes a set, and Option D reverses the intended key-value direction.", + "code_context": "list_1 = [ ... ]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-17.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json new file mode 100644 index 0000000..4b24f31 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q09-q16-legacy-reverified.json @@ -0,0 +1,205 @@ +{ + "exam_id": "sample-final-plus-answers", + "question_updates": [ + { + "number": 9, + "topic": "Datetime parsing", + "question": "Take a look at the following code segment.\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "The first string contains `/`, so it is parsed as month/day/year and gives month 3. The second string contains neither `-` nor `/`, so it becomes `None`. The third contains `-`, so it is parsed as day-month-year and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-15.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 10, + "topic": "Datetime day-of-year", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives a `timedelta`; taking `.days` and adding 1 makes January 1 equal to day 1. The other options either misuse `timedelta`, add an integer directly to a `datetime` difference, or use an invalid date.", + "code_context": "day_of_year(datetime(2022, 2, 1))\n# should return 32", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-16.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 11, + "topic": "Dictionary comprehension", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Only option A is a dictionary comprehension with each string as the key and its length as the value. The others create a list, a set, or a dictionary with the mapping reversed.", + "code_context": "list_1 = [...]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-17.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 12, + "topic": "Case swapping", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[x if x in 'abcdefghijklmnopqrstuvwxyz'.upper() else x.lower() for x in list_1]", + "c": "Both achieve what you want", + "d": "None achieves what you want" + }, + "correct": "a", + "explanation": "Option A explicitly checks whether each character is lowercase and flips the case accordingly. Option B leaves uppercase letters unchanged instead of converting them to lowercase.", + "code_context": "list_1 = [...]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-18.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 13, + "topic": "Comparisons and types", + "question": "Suppose you have three variables x, y, z, as follows:\nx = '3'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string `'3'` is not equal to the integer `3`, while `3 == 3.0` is `True`. The chained comparison `x == y == z` means `(x == y) and (y == z)`, so it is `False`.", + "code_context": "x = '3'\ny = 3\nz = 3.0", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-19.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 14, + "topic": "Loops", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. (In the first iteration, just take the previous number to be 0.)\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e.: only the sums).", + "options": { + "a": "i = 0\nwhile i <= 10:\n print(i + (i-1))\n i += 1", + "b": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "b", + "explanation": "Option B correctly tracks the previous number and starts the loop at 1, producing the required sums. Option A starts at 0 and prints `-1` on the first iteration, so it does not match the specification.", + "code_context": "# target outputs: 1, 3, 5, ..., 19", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-20.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 15, + "topic": "Functions and scope", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "Result is a local name and cannot be referenced outside of the function.", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "`result` is defined inside `cube`, so it exists only within the function scope. The line `print(result)` is outside the function, where that local name is not defined.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-21.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 16, + "topic": "Lambda functions", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "The first lambda returns `1 + 2 = 3`, the second returns `1 * 2 = 2`, and `3 ** 2` equals `9`.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-22.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json new file mode 100644 index 0000000..d8980ef --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/sample-final-plus-answers-q17-q24-legacy-reverified.json @@ -0,0 +1,206 @@ +{ + "exam_id": "sample-final-plus-answers", + "question_updates": [ + { + "number": 17, + "topic": "Empty-sequence equality chain", + "question": "You have the following function called main:\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat will be printed by the following lines:\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))", + "options": { + "a": "True\nFalse\nFalse", + "b": "False\nFalse\nTrue", + "c": "True\nFalse\nTrue", + "d": "True\nTrue\nTrue" + }, + "correct": "d", + "explanation": "The first call builds [True, True, True], the second call builds [False, False, False], and the third call also builds [False, False, False]. In all three cases the chained equality compares three identical booleans, so each printed result is True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-23.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 18, + "topic": "List chunking into sublists", + "question": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nFor example:\nIf you have the original list x as:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nHow do you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:(i + 3)] for i in range(0, 7, 3)]", + "b": "y = [x[i[0]::3] for i in enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "a", + "explanation": "Option A slices the list in chunks of length 3 starting at indices 0, 3, and 6, which produces the three required sublists in order.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-24.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 19, + "topic": "Dictionary running totals", + "question": "You have to write a function called main that accepts a dictionary as an input argument.\nBoth the keys and the values of the input are integers.\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary whose keys are smaller than or equal to the output key in question.\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "b": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "c": "Both of the above work as intended", + "d": "None of the above works as intended" + }, + "correct": "c", + "explanation": "The first program computes each output value by summing all input values whose keys are less than or equal to the current key. The second program accumulates values in ascending key order, which yields the same running totals for each key.", + "code_context": "main({5: 1, 2: 5, 4: 2})\n# expected result:\n# {5: 8, 2: 5, 4: 7}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-25.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 20, + "topic": "Dictionary equality with zip and enumerate", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) produces key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same key-value pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-27.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "The preceding rendered page is an empty feedback/interstitial page; the verified question appears on page-27.png." + ] + } + }, + { + "number": 21, + "topic": "Dictionary iteration semantics", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not (key, value) pairs, so `for key, value in d1:` is invalid. The other three variants all sum the dictionary values correctly.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-28.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 22, + "topic": "String count method", + "question": "You have the following string\nx = 'Amsterdam'\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method `count` must be called on the string object itself. `x.count('a')` returns 1 for the lowercase 'a' in 'Amsterdam'.", + "code_context": "x = 'Amsterdam'", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-29.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 23, + "topic": "Higher-order function returning 30", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "The first call returns (1+5)+(2+5)+(3+5)+(4+5)=30, and the second returns 1^2+2^2+3^2+4^2=30. Both produce the requested result.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-30.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 24, + "topic": "Circle area imports and aliases", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C aliases the module as `constants`, so `math.pi` is not defined there. The other three options reference pi correctly.", + "code_context": "# area formula\n# pi * r ** 2", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-31.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json new file mode 100644 index 0000000..3860b92 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q01-q03-legacy-reverified.json @@ -0,0 +1,81 @@ +{ + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_updates": [ + { + "number": 1, + "topic": "6-OOP-1", + "question": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor, then the \"mode\" attribute should be equal to \"land\".\n\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A defines an initializer with a required vehicle name and a default mode of \"land\", then stores both on the instance using self.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-02.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 2, + "topic": "6-OOP-2", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The reviews are 5, 3, and 3, so the average is 11 / 3 = 3.666..., which show_rating rounds to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only." + ] + } + }, + { + "number": 3, + "topic": "6-strings-1", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\n\nFor example, if:\nstudents = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 7.5.\nBernard has received a grade of 8.0.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']:.1f}.\")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {grade:.1f}.\")", + "c": "for student in students:\n print(f\"{student[\\\"Name\\\"]} has received a grade of {student[\\\"Grade\\\"]:.1f}.\")", + "d": "for student, grade in students:\n print(f\"{student} has received a grade of {grade:.1f}.\")" + }, + "correct": "a", + "explanation": "Option A iterates through each dictionary in the list and formats the student's name and grade correctly to one decimal place. The other options use the wrong iteration pattern or invalid access pattern for this data structure.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-03.png" + ], + "notes": [ + "Legacy-seeded record re-verified from rendered PNG pages only.", + "Option C's quote style is small in the rendered page and should be human-confirmed if exact punctuation matters." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json new file mode 100644 index 0000000..674a681 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q04-q06-legacy-reverified.json @@ -0,0 +1,83 @@ +{ + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_updates": [ + { + "number": 4, + "topic": "6-strings-2", + "question": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character, at various places).\n\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A does not work because strings are immutable and number.replace(\"-\", \"\") returns a new string that is ignored. The function then returns the original unmodified number.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# all should return \"0205251400\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 5, + "topic": "7-pandas-new_column-1", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] + df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x + df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\" + \"B\"]", + "d": "df[\"C\"] = df[\"A\" + \"B\"]" + }, + "correct": "a", + "explanation": "Option A performs elementwise addition between columns A and B and stores the result in column C. The other options either misuse map, index into the columns object incorrectly, or look for a non-existent combined column name.", + "code_context": "df has numeric columns \"A\" and \"B\"; column \"C\" should contain their sum.", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-04.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + }, + { + "number": 6, + "topic": "7-pandas-selection-1", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that only contains those elements of column \"B\" in df that have an even-numbered index. Which of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters rows whose index is even and selects column B while keeping the result as a DataFrame by using [[\"B\"]]. Option D would return a Series, not a DataFrame, and the other options do not select the requested data correctly.", + "code_context": "df printed as:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Legacy record re-verified from PNG pages." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json new file mode 100644 index 0000000..0ad1a9a --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q07-q12.json @@ -0,0 +1,156 @@ +{ + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_updates": [ + { + "number": 7, + "topic": "7-pandas-sorting-1", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\n\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False)[[\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A sorts the entire DataFrame by index in descending order and would include rows 5 and 1 as well, so it would not match df2. The other options all produce rows 4, 3, and 2 with columns A, C, and D.", + "code_context": "print(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-05.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 8, + "topic": "7-pandas-string-1", + "question": "There is a pandas Series called s, which contains Dutch municipality and corresponding province names, separated by a semicolon and a whitespace. The following, for example, is an element of this Series: \"Amsterdam; Noord-Holland\".\n\nYou'd like to create a new Series that only contains the municipality names from s in the same order. Which of the following code lines will achieve what you want?", + "options": { + "a": "s.map(lambda x: x.split(\"; \")[0])", + "b": "s.split(\"; \")[0]", + "c": "s.lambda(x.split(\"; \"))", + "d": "s.str[:9]" + }, + "correct": "a", + "explanation": "Option A applies split('; ') to each element in the Series and takes the first part, which is the municipality name. The other options either do not operate elementwise or do not reliably extract the municipality name.", + "code_context": "Example element in s:\n\"Amsterdam; Noord-Holland\"", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 9, + "topic": "8-datetime-1", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "\"03/02/2013\" matches %m/%d/%Y and gives month 3, \"03.02.2013\" matches neither branch and becomes None, and \"03-02-2013\" matches %d-%m-%Y and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-06.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 10, + "topic": "8-datetime-2", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives the zero-based offset in days, and adding 1 converts it to the day number within the year. The other options either return or manipulate timedeltas incorrectly or use an invalid date.", + "code_context": "Example target behavior:\nday_of_year(datetime(2022, 2, 1))\n# returns 32", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 11, + "topic": "8-dict_comprehension-1", + "question": "You have a list of strings called list_1, in which every element is unique.\n\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the dictionary comprehension that maps each string to its length. Option B creates a list, option C creates a set, and option D reverses the intended key-value relation.", + "code_context": "list_1 contains unique strings.", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 12, + "topic": "8-list_comprehension-1", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\n\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[letter.upper() for letter in list_1 if letter.islower() else letter.lower()]", + "c": "[letter.lower() for letter in list_1 if letter.isupper()] + [letter.upper() for letter in list_1 if letter.islower()]", + "d": "[letter.capitalize() for letter in list_1 if not letter.iscapitalized()]" + }, + "correct": "a", + "explanation": "Option A flips the case of each letter while preserving the original order of the list. The other options either have invalid comprehension syntax, change the order, or use a non-existent string method.", + "code_context": "list_1 contains letters with mixed case.", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only.", + "Option D uses the method name exactly as it appears in the rendered page; it looks like 'iscapitalized()'." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json new file mode 100644 index 0000000..5e010a9 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q13-q18.json @@ -0,0 +1,155 @@ +{ + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_updates": [ + { + "number": 13, + "topic": "Basic logic", + "question": "Suppose you have three variables x, y, z as follows:\n\nx = 'x'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string 'x' is not equal to the integer 3 or the float 3.0, so the first and third comparisons are False. The integer 3 and float 3.0 are equal in Python, so the second comparison is True. The chained comparison is False because x == y is False.", + "code_context": "x = 'x'\ny = 3\nz = 3.0\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 14, + "topic": "Basic loop", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. In the first iteration, just take the previous number to be 0.\n\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e. only the sums).", + "options": { + "a": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "b": "i = 0\nwhile i <= 10:\n print(i + (i - 1))\n i += 1", + "c": "Both of the above", + "d": "Neither of the above" + }, + "correct": "a", + "explanation": "A keeps track of the previous number and prints each sum correctly from 1 + 0 through 10 + 9. B does not use the required previous-value logic and prints the wrong sums.", + "code_context": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 15, + "topic": "Basic scope", + "question": "Executing the following program will produce an error. Why?\n\ndef cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "options": { + "a": "Result is a local variable and cannot be referenced outside of the function", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "result is created inside the function, so it is local to cube and is not available at the top level where print(result) is executed.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 16, + "topic": "List lambda", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\n\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "list_1[0](1, 2) returns 3 and list_1[1](1, 2) returns 2, so the expression becomes 3 ** 2, which is 9.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-08.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 17, + "topic": "List logic", + "question": "You have the following function called main:\n\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat are the outputs of the following lines:\nmain([[], (), []])\nmain([[1], [2, 2], [3, 3, 3]])\nmain([[1], [2], [3]])", + "options": { + "a": "True\nTrue\nTrue", + "b": "True\nFalse\nTrue", + "c": "True\nFalse\nFalse", + "d": "False\nFalse\nTrue" + }, + "correct": "a", + "explanation": "For the first call, each element has length 0, so y becomes [True, True, True] and the comparison is True. In the second and third calls, each element has non-zero length, so y becomes [False, False, False] and the chained equality is also True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 18, + "topic": "List loop", + "question": "How do you break a list into a list of lists, in which a sub-list consists of 3 values each?\n\nFor example, if the original list x is:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nthen how would you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:i + 3] for i in range(0, 7, 3)]", + "b": "y = [x[0::3] for i, enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of the above works" + }, + "correct": "a", + "explanation": "A slices the list into consecutive groups of three elements. B does not produce the required nested lists.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-09.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json new file mode 100644 index 0000000..a368db9 --- /dev/null +++ b/data/vision_exam_pipeline/review_drops/trial-final-exam-solutions-introduction-to-python-3077951-q19-q24.json @@ -0,0 +1,155 @@ +{ + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_updates": [ + { + "number": 19, + "topic": "trial-dictionary-1", + "question": "You have to write a function called main that accepts a dictionary as an input argument. Both the keys and the values of the input are integers.\n\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary, whose keys are smaller than, or equal to, the output key in question.\n\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\n\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "b": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "c": "Both of the above works as intended", + "d": "None of the above work as intended" + }, + "correct": "c", + "explanation": "Option A builds cumulative sums over the sorted keys, and option B directly computes the sum of values whose keys are less than or equal to each output key. Both produce the intended dictionary values.", + "code_context": "Example target behavior:\nmain({5: 1, 2: 5, 4: 2})\n# returns a dictionary equal to {5: 8, 2: 5, 4: 7}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 20, + "topic": "trial-dictionary-2", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) creates key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-11.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 21, + "topic": "trial-dictionary-3", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\n\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not key-value pairs, so `for key, value in d1:` does not work as intended. The other three options all sum the dictionary values and print the same result.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 22, + "topic": "trial-functions-1", + "question": "You have the following string\nx = 'Amsterdam'\n\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method must be called on the string object itself, so `x.count('a')` is the correct form. In 'Amsterdam', there is one lowercase 'a', while the initial uppercase 'A' is not counted.", + "code_context": "x = 'Amsterdam'", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-12.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 23, + "topic": "trial-functions-2", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "For option A, the function returns 6 + 7 + 8 + 9 = 30. For option B, it returns 1 + 4 + 9 + 16 = 30. Both calls therefore produce 30.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + }, + { + "number": 24, + "topic": "trial-functions-3", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\n\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C imports the module under the name `constants`, but then tries to access `math.pi`, where `math` is not defined. The other options all reference pi correctly and would print the correct area.", + "code_context": "Area formula: πr²", + "provenance": { + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-13.png" + ], + "notes": [ + "Reviewed from rendered PNG pages only." + ] + } + } + ] +} diff --git a/data/vision_exam_pipeline/review_packets/round1.json b/data/vision_exam_pipeline/review_packets/round1.json new file mode 100644 index 0000000..4e34178 --- /dev/null +++ b/data/vision_exam_pipeline/review_packets/round1.json @@ -0,0 +1,900 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T20:16:23Z", + "round": "round1", + "ready_for_human_review": true, + "input_paths": { + "evaluations": "data/vision_exam_pipeline/evaluations/round1.json", + "synthesis": "data/vision_exam_pipeline/synthesis/round1.json", + "analytics": "data/vision_exam_pipeline/analytics/round1.json", + "selectable_items": "data/vision_exam_pipeline/selectable_items_snapshot.json" + }, + "summary": { + "completed_evaluations": 168, + "certain_count": 88, + "partial_count": 40, + "insufficient_count": 40, + "theme_count": 9, + "top_snippet_count": 123 + }, + "review_sequence": [ + { + "order": 1, + "theme_id": "strings_text_methods", + "theme_name": "Strings, Indexing, and Text Methods", + "priority": "high", + "question_count": 52, + "suggestion_count": 70, + "suggested_direction": "add_this" + }, + { + "order": 2, + "theme_id": "loops_iteration", + "theme_name": "Loops, Iteration, and Comprehensions", + "priority": "high", + "question_count": 14, + "suggestion_count": 19, + "suggested_direction": "add_this" + }, + { + "order": 3, + "theme_id": "functions_scope", + "theme_name": "Functions, Returns, and Scope", + "priority": "high", + "question_count": 11, + "suggestion_count": 31, + "suggested_direction": "add_this" + }, + { + "order": 4, + "theme_id": "dicts_tuples_sets", + "theme_name": "Dictionaries, Tuples, and Sets", + "priority": "medium", + "question_count": 2, + "suggestion_count": 6, + "suggested_direction": "add_this" + }, + { + "order": 5, + "theme_id": "oop_self_attributes", + "theme_name": "OOP, self, and Attributes", + "priority": "medium", + "question_count": 1, + "suggestion_count": 7, + "suggested_direction": "add_this" + }, + { + "order": 6, + "theme_id": "operators_boolean_logic", + "theme_name": "Operators and Boolean Logic", + "priority": "medium", + "question_count": 0, + "suggestion_count": 7, + "suggested_direction": "add_this" + }, + { + "order": 7, + "theme_id": "pandas_core", + "theme_name": "Pandas Core Operations", + "priority": "medium", + "question_count": 0, + "suggestion_count": 7, + "suggested_direction": "add_this" + }, + { + "order": 8, + "theme_id": "miscellaneous_exam_specific", + "theme_name": "Miscellaneous Exam-Specific Gaps", + "priority": "selective", + "question_count": 0, + "suggestion_count": 3, + "suggested_direction": "add_this" + }, + { + "order": 9, + "theme_id": "datetime_time", + "theme_name": "Datetime and Timedelta", + "priority": "selective", + "question_count": 0, + "suggestion_count": 1, + "suggested_direction": "add_this" + } + ], + "themes": [ + { + "theme_id": "strings_text_methods", + "theme_name": "Strings, Indexing, and Text Methods", + "priority": "high", + "question_count": 52, + "partial_question_count": 19, + "insufficient_question_count": 33, + "suggestion_count": 70, + "recommended_direction_counts": { + "add_this": 70 + }, + "source_exam_count": 7, + "representative_gaps": [ + "The snippets lack a clear explanation of the difference between label-based (.loc) and integer-position-based (.iloc) indexing, specifically regarding the inclusivity of the stop index.", + "The snippets provide zero explanation for Pandas-specific method syntax required to evaluate the options.", + "The snippets lack a clear example of dictionary comprehension syntax and the specific use of slicing [:-1] to remove a trailing character in a list context." + ], + "representative_suggestions": [ + "Key Point: Boolean String Methods. Methods like .islower(), .isupper(), and .isdigit() return True only if the string contains at least one character and all characters meet the criteria. Importantly, .islower() returns False for spaces, punctuation, and numbers as they are not lowercase letters.", + "Create a common question snippet: 'How do zip() and floor division (//) work?'. Content: `zip(list1, list2)` pairs elements by index: (list1[0], list2[0]), (list1[1], list2[1]). `//` is floor division, which divides and rounds down to the whole number (e.g., 5 // 2 = 2).", + "Expand the search text/explanation to explicitly define why option A ([::-2][::-1]) results in [2, 4, 6, 8, 10] (it reverses the reversed slice)." + ] + }, + { + "theme_id": "loops_iteration", + "theme_name": "Loops, Iteration, and Comprehensions", + "priority": "high", + "question_count": 14, + "partial_question_count": 10, + "insufficient_question_count": 4, + "suggestion_count": 19, + "recommended_direction_counts": { + "add_this": 19 + }, + "source_exam_count": 7, + "representative_gaps": [ + "The main conceptual hurdle is the implicit conversion of Booleans to integers during a sum operation, and the behavior of an empty match (summing all False values).", + "The main missing piece is a clear explanation of how range(start, stop) behaves regarding the upper bound.", + "There is a complete lack of 'lambda' syntax explanation in the recommended snippets." + ], + "representative_suggestions": [ + "Create a 'Comprehension Syntax' summary card: 1. Dictionary: {key: value for item in iterable}, 2. List: [value for item in iterable], 3. Set: {value for item in iterable}.", + "List Comprehension: [expression for item in iterable] creates a new list by running the expression for every item. Example: [i*2 for i in range(3)] generates [0, 2, 4].", + "Create a snippet explaining the range() function: range(0, 10) produces numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The number 10 is not included." + ] + }, + { + "theme_id": "functions_scope", + "theme_name": "Functions, Returns, and Scope", + "priority": "high", + "question_count": 11, + "partial_question_count": 9, + "insufficient_question_count": 2, + "suggestion_count": 31, + "recommended_direction_counts": { + "add_this": 27, + "consider_instead": 4 + }, + "source_exam_count": 7, + "representative_gaps": [ + "Existing snippets provide the 'what' (rules) and the 'where' (class), but miss the 'why' regarding the logical structure of comparison functions.", + "Existing snippets cover the 'how' for the correct options but don't explicitly warn against the common mistake of passing a Series into .map().", + "The primary gap is the 'implicit return' behavior. A student can deduce x=0 and see that neither 'if x > 0' nor 'if x < 0' will run, but they won't know what happens when a function 'runs out' of code." + ], + "representative_suggestions": [ + "Title: 'Comparing Objects with Multiple Criteria'. Snippet: 'When comparing two objects (A, B) based on multiple rules, remember that ! (A > B) does not imply (B > A). Example: def compare(self, other): if self.val > other.val and self.count >= other.count: return self; if other.val > self.val and other.count >= self.count: return other; return None'", + "Create a snippet titled 'Conditional Expressions vs Statements' showing: 'return \"Yes\" if check else \"No\"' is equivalent to 'if check: return \"Yes\" else: return \"No\"'.", + "Add a compare method: def is_better(self, other): return self.average() > other.average()" + ] + }, + { + "theme_id": "dicts_tuples_sets", + "theme_name": "Dictionaries, Tuples, and Sets", + "priority": "medium", + "question_count": 2, + "partial_question_count": 1, + "insufficient_question_count": 1, + "suggestion_count": 6, + "recommended_direction_counts": { + "add_this": 6 + }, + "source_exam_count": 5, + "representative_gaps": [ + "Missing the specific rule that Python dictionaries compare equal if they have the same key-value pairs, regardless of order.", + "The primary gaps are the mathematical syntax for parity checking and exponentiation, as well as the explicit distinction between integer accumulation and list appending." + ], + "representative_suggestions": [ + "Create a 'Sequence Properties' card showing that len([]) == 0, len({}) == 0, and len('') == 0, and explaining that a == b == c is only True if all three are identical.", + "Add a snippet explaining 'Sorted Dictionary Iteration': 'To process a dictionary in order of its keys, use `for key in sorted(my_dict.keys()):`. This ensures you visit keys from smallest to largest, which is useful for calculating running totals.'", + "Create a snippet showing: 'for key in sorted(prices.keys()): ...' and another showing 'sub_total = sum([val for key, val in d.items() if key < 10])'." + ] + }, + { + "theme_id": "oop_self_attributes", + "theme_name": "OOP, self, and Attributes", + "priority": "medium", + "question_count": 1, + "partial_question_count": 1, + "insufficient_question_count": 0, + "suggestion_count": 7, + "recommended_direction_counts": { + "consider_instead": 3, + "add_this": 4 + }, + "source_exam_count": 5, + "representative_gaps": [ + "No snippet explicitly demonstrates the difference between a method reference and a method call (e.g., self.rating vs self.rating()), nor does any snippet show one instance calling a method on another instance (other.rating())." + ], + "representative_suggestions": [ + "Update the search_text to show a snippet of the code for the Vehicle class, specifically including a default value for the 'mode' attribute (e.g., mode='land').", + "Create a snippet explaining 'self' as a reference to the current instance, used to access attributes defined in __init__.", + "Title: Instance Attributes and 'self'. Content: 'To make an attribute available on an object (like my_car.name), you must assign it to self inside the __init__ method (e.g., self.name = vehicle_name). Without self, the variable only exists temporarily during creation.'" + ] + }, + { + "theme_id": "operators_boolean_logic", + "theme_name": "Operators and Boolean Logic", + "priority": "medium", + "question_count": 0, + "partial_question_count": 0, + "insufficient_question_count": 0, + "suggestion_count": 7, + "recommended_direction_counts": { + "consider_instead": 3, + "add_this": 4 + }, + "source_exam_count": 5, + "representative_gaps": [], + "representative_suggestions": [ + "Ensure the 'search_text' includes the full code for options a and b and clarifies why both work, matching the provided question explanation.", + "Create a snippet showing: 'my_list = [True, False]; len([]); my_list[0] # Returns True'.", + "Snippet: Comparison Operators. x >= y means 'x is greater than or equal to y'. x < y means 'x is less than y'. Example: 0 >= 0 is True." + ] + }, + { + "theme_id": "pandas_core", + "theme_name": "Pandas Core Operations", + "priority": "medium", + "question_count": 0, + "partial_question_count": 0, + "insufficient_question_count": 0, + "suggestion_count": 7, + "recommended_direction_counts": { + "add_this": 6, + "consider_instead": 1 + }, + "source_exam_count": 6, + "representative_gaps": [], + "representative_suggestions": [ + "Create a snippet titled 'Pandas Boolean Filtering' showing: df_filtered = df[df['Salary'] > 50000].", + "Ensure the example code includes a lambda with a condition, e.g., s.map(lambda x: 'High' if x > 10 else 'Low').", + "Create a snippet titled 'Lambda Basics' that explains: 'lambda x: x + 5' means 'take x and add 5 to it'." + ] + }, + { + "theme_id": "miscellaneous_exam_specific", + "theme_name": "Miscellaneous Exam-Specific Gaps", + "priority": "selective", + "question_count": 0, + "partial_question_count": 0, + "insufficient_question_count": 0, + "suggestion_count": 3, + "recommended_direction_counts": { + "add_this": 3 + }, + "source_exam_count": 3, + "representative_gaps": [], + "representative_suggestions": [ + "Add a snippet demonstrating: count = sum([val == target for val in collection]). Show that this results in an integer, even if the count is zero.", + "Add a foundational snippet explaining that .loc[2:4] includes labels 2, 3, and 4, whereas .iloc[[3, 2, 1]] selects the 4th, 3rd, and 2nd rows respectively.", + "Update the search_text to include the full solution code for option C: word_lengths = {word: len(word) for word in words}." + ] + }, + { + "theme_id": "datetime_time", + "theme_name": "Datetime and Timedelta", + "priority": "selective", + "question_count": 0, + "partial_question_count": 0, + "insufficient_question_count": 0, + "suggestion_count": 1, + "recommended_direction_counts": { + "add_this": 1 + }, + "source_exam_count": 1, + "representative_gaps": [], + "representative_suggestions": [ + "Add a 'Topic Detail' or 'Cheat Sheet' item for Week 8 (Datetime) covering: 1. datetime(year, month, day, hour, minute) 2. timedelta(minutes=N) 3. Comparing datetimes using <, >, ==." + ] + } + ], + "top_existing_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "label": "Week 5 • Working With Values • recommended/source_exam", + "excerpt": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code...", + "week": 5, + "topic": "Working With Values", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 10, + "top_three_count": 20, + "minimal_set_count": 18, + "weighted_score": 86 + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "label": "Week 2 • Loops • recommended/source_exam", + "excerpt": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\" Which of the following code snippets will give the same o...", + "week": 2, + "topic": "Loops", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 5, + "top_three_count": 21, + "minimal_set_count": 12, + "weighted_score": 60 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "label": "Week 5 • Inspecting and Selecting Data • recommended/source_exam", + "excerpt": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want? A B...", + "week": 5, + "topic": "Inspecting and Selecting Data", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 6, + "top_three_count": 13, + "minimal_set_count": 11, + "weighted_score": 53 + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "label": "Week 2 • Dictionaries and Mappings • recommended/source_exam", + "excerpt": "Assume you already have a list of strings called words. You need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are the...", + "week": 2, + "topic": "Dictionaries and Mappings", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 4, + "top_three_count": 21, + "minimal_set_count": 10, + "weighted_score": 53 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "label": "Week 5 • Pandas Core Structures • recommended/source_exam", + "excerpt": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the...", + "week": 5, + "topic": "Pandas Core Structures", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 4, + "top_three_count": 15, + "minimal_set_count": 12, + "weighted_score": 51 + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "label": "Week 4 • OOP Fundamentals • recommended/source_exam", + "excerpt": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another b...", + "week": 4, + "topic": "OOP Fundamentals", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 7, + "top_three_count": 11, + "minimal_set_count": 9, + "weighted_score": 50 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "label": "Week 4 • OOP Fundamentals • recommended/source_exam", + "excerpt": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction. The \"name\" attri...", + "week": 4, + "topic": "OOP Fundamentals", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 3, + "top_three_count": 15, + "minimal_set_count": 11, + "weighted_score": 46 + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "label": "Week 3 • Return Behavior • recommended/source_exam", + "excerpt": "Assume sum_even_in_list(l1) filters non-integers and sums even integers. You want sum_even_integers that accepts a flexible number of arguments. For example: sum_even_integers(1,'2...", + "week": 3, + "topic": "Return Behavior", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 5, + "top_three_count": 10, + "minimal_set_count": 7, + "weighted_score": 39 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "label": "Week 6 • Datetime • recommended/source_exam", + "excerpt": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year? A B C D A Subtracting two datetime objects results ...", + "week": 6, + "topic": "Datetime", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 5, + "top_three_count": 8, + "minimal_set_count": 8, + "weighted_score": 39 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "label": "Week 3 • Defining and Calling Functions • recommended/source_exam", + "excerpt": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has...", + "week": 3, + "topic": "Defining and Calling Functions", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 5, + "top_three_count": 6, + "minimal_set_count": 8, + "weighted_score": 37 + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "label": "Week 5 • Pandas Core Structures • recommended/source_exam", + "excerpt": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the correspondin...", + "week": 5, + "topic": "Pandas Core Structures", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 2, + "top_three_count": 11, + "minimal_set_count": 7, + "weighted_score": 31 + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "label": "Week 2 • Dictionaries and Mappings • recommended/source_exam", + "excerpt": "You have two lists representing the names and ages of individuals: names = ['Alice', 'Bob', 'Charlie', 'David'] ages = [25, 30, 35, 40] You need to create a dictionary called perso...", + "week": 2, + "topic": "Dictionaries and Mappings", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 1, + "top_three_count": 13, + "minimal_set_count": 7, + "weighted_score": 30 + }, + { + "item_id": "aiq-5", + "label": "Week 5 • Inspecting and Selecting Data • aiQuestions/ai_common_question", + "excerpt": "UnboundLocalError If a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line", + "week": 5, + "topic": "Inspecting and Selecting Data", + "bucket": "aiQuestions", + "item_type": "ai_common_question", + "best_single_count": 3, + "top_three_count": 8, + "minimal_set_count": 6, + "weighted_score": 29 + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "label": "Week 3 • Arguments • recommended/source_exam", + "excerpt": "Suppose you have the following function: def add_numbers(num1, num2 = 10, num3 = 20): return num1 + num2 + num3 What are the outputs if we call the function three times as follows:...", + "week": 3, + "topic": "Arguments", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 4, + "top_three_count": 8, + "minimal_set_count": 4, + "weighted_score": 28 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "label": "Week 5 • Inspecting and Selecting Data • recommended/source_exam", + "excerpt": "You have a pandas DataFrame called df that looks like this, when printed: A B C D 1 9.1 9.5 9.0 6.0 2 6.4 8.2 7.5 1.7 3 2.5 5.3 8.8 3.0 4 6.7 3.6 7.2 6.9 5 8.4 1.9 8.2 3.3 6 8.1 8....", + "week": 5, + "topic": "Inspecting and Selecting Data", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 2, + "top_three_count": 10, + "minimal_set_count": 6, + "weighted_score": 28 + }, + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "label": "Week 2 • Lists and Sets • recommended/source_exam", + "excerpt": "What is the output of the following code segment? a b c d c The list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 sati...", + "week": 2, + "topic": "Lists and Sets", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 4, + "top_three_count": 5, + "minimal_set_count": 5, + "weighted_score": 27 + }, + { + "item_id": "manual-oop-state-compare", + "label": "Week 4 • OOP Fundamentals • aiExamples/ai_example", + "excerpt": "Trace `self` state across multiple method calls class Book: def __init__(self, title): self.title = title self.scores = [] def add_review(self, score): self.scores.append(score) de...", + "week": 4, + "topic": "OOP Fundamentals", + "bucket": "aiExamples", + "item_type": "ai_example", + "best_single_count": 4, + "top_three_count": 5, + "minimal_set_count": 5, + "weighted_score": 27 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "label": "Week 3 • Defining and Calling Functions • recommended/source_exam", + "excerpt": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argum...", + "week": 3, + "topic": "Defining and Calling Functions", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 1, + "top_three_count": 14, + "minimal_set_count": 4, + "weighted_score": 25 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "label": "Week 1 • Objects and Names • recommended/source_exam", + "excerpt": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z) A B C D A '3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is Fa...", + "week": 1, + "topic": "Objects and Names", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 4, + "top_three_count": 4, + "minimal_set_count": 4, + "weighted_score": 24 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "label": "Week 3 • Defining and Calling Functions • recommended/source_exam", + "excerpt": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key? A B C...", + "week": 3, + "topic": "Defining and Calling Functions", + "bucket": "recommended", + "item_type": "source_exam", + "best_single_count": 3, + "top_three_count": 5, + "minimal_set_count": 5, + "weighted_score": 24 + } + ], + "week_summary": [ + { + "week": 2, + "top1_unique_snippets": 22, + "top3_unique_snippets": 34, + "minimal_set_unique_snippets": 31, + "minimal_set_unused_snippets": 62, + "unused_snippet_ids": [ + "cs-3e39a2f12f", + "cs-curated-hw-conditions-first-match-wins", + "cs-curated-hw-dict-delete-shared-keys", + "cs-curated-hw-dict-digit-frequency", + "cs-curated-hw-dict-project-values-sorted-keys", + "cs-curated-hw-loops-enumerate-mark-max", + "cs-curated-hw-loops-market-clearing", + "cs-curated-hw-loops-nested-pairwise-dict", + "cs-curated-hw-loops-zip-filter-pairs", + "cs-fc8bdeb969", + "exam-Resit 22/23-1-w2-lists-and-sets", + "exam-extra_practice-12-w2-dictionaries-and-mappings", + "exam-extra_practice-3-w2-dictionaries-and-mappings", + "exam-extra_practice-8-w2-dictionaries-and-mappings", + "exam-midterm_2023-1-w2-conditions", + "exam-midterm_2023-15-w2-lists-and-sets", + "exam-midterm_2023-2-w2-loops", + "exam-midterm_2023-5-w2-dictionaries-and-mappings", + "exam-midterm_2023-6-w2-dictionaries-and-mappings", + "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "exam-midterm_2024-10-w2-dictionaries-and-mappings", + "exam-midterm_2024-11-w2-dictionaries-and-mappings", + "exam-midterm_2024-12-w2-dictionaries-and-mappings", + "exam-midterm_2024-17-w2-loops", + "exam-midterm_2024-20-w2-loops", + "exam-midterm_2024-21-w2-loops", + "exam-midterm_2024-22-w2-lists-and-sets", + "exam-midterm_2024-23-w2-lists-and-sets", + "exam-midterm_2024-24-w2-lists-and-sets", + "exam-midterm_2024-3-w2-loops", + "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "exam-midterm_2024-8-w2-dictionaries-and-mappings", + "exam-midterm_2024-9-w2-loops", + "exam-trial_midterm-13-w2-conditions", + "exam-trial_midterm-2-w2-dictionaries-and-mappings", + "exam-trial_midterm-23-w2-dictionaries-and-mappings", + "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "kp-1-d3", + "kp-manual-break-continue", + "kp-manual-enumerate", + "kp-manual-loop-core", + "kp-manual-precedence", + "kp-manual-ternary", + "kp-manual-while-truthy", + "ks-08ac820c2f", + "ks-4258f15a6c", + "ks-4b427a2425", + "ks-4c6274845e", + "ks-59aaf6b0ee", + "ks-624034d573" + ] + }, + { + "week": 3, + "top1_unique_snippets": 22, + "top3_unique_snippets": 34, + "minimal_set_unique_snippets": 26, + "minimal_set_unused_snippets": 38, + "unused_snippet_ids": [ + "aiq-7", + "cs-curated-hw-hof-nested-helper-hhi", + "exam-extra_practice-2-w3-scope", + "exam-extra_practice-7-w3-return-behavior", + "exam-midterm_2023-11-w3-higher-order-patterns", + "exam-midterm_2023-13-w3-higher-order-patterns", + "exam-midterm_2023-3-w3-scope", + "exam-midterm_2024-1-w3-return-behavior", + "exam-midterm_2024-13-w3-arguments", + "exam-midterm_2024-14-w3-arguments", + "exam-midterm_2024-19-w3-higher-order-patterns", + "exam-midterm_2024-5-w3-scope", + "exam-trial_midterm-17-w3-higher-order-patterns", + "kp-2-d2", + "kp-3-d2", + "kp-manual-scope-global", + "kp-manual-scope-local", + "kp-manual-scope-unbound", + "ks-00b2983ca8", + "ks-14515a5856", + "ks-40fee04740", + "ks-994a4083e3", + "ks-ab66f3bab6", + "ks-d1a2d7739d", + "ks-d26b85265c", + "ks-db93da9e3e", + "ks-e09d7f145b", + "ks-f5d65c7e89", + "manual-call-vs-index", + "manual-global", + "manual-list-of-dicts-loop", + "manual-local-name", + "manual-scope-global-change", + "manual-scope-local-name", + "manual-scope-rebind-parameter", + "manual-scope-unbound", + "manual-string-return-shape", + "manual-unboundlocal" + ] + }, + { + "week": 1, + "top1_unique_snippets": 8, + "top3_unique_snippets": 18, + "minimal_set_unique_snippets": 15, + "minimal_set_unused_snippets": 57, + "unused_snippet_ids": [ + "cs-09e2b215ee", + "cs-23b2cfd4d6", + "cs-266616a010", + "cs-3cb4b8e8f9", + "cs-4155022ebf", + "cs-4f8a5f420b", + "cs-5b89a10dcd", + "cs-6d0d650063", + "cs-7eb8617d28", + "cs-814a07a136", + "cs-beb6591b24", + "cs-c25503e5db", + "cs-curated-hw-seq-nth-occurrence", + "cs-curated-hw-seq-slice-between-sentinels", + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "exam-extra_practice-11-w1-objects-and-names", + "exam-midterm_2023-12-w1-functions-and-imports", + "exam-midterm_2023-4-w1-objects-and-names", + "exam-midterm_2024-16-w1-functions-and-imports", + "exam-midterm_2024-4-w1-objects-and-names", + "exam-midterm_2024-6-w1-objects-and-names", + "exam-trial_midterm-11-w1-objects-and-names", + "exam-trial_midterm-12-w1-objects-and-names", + "exam-trial_midterm-14-w1-objects-and-names", + "exam-trial_midterm-16-w1-objects-and-names", + "exam-trial_midterm-18-w1-objects-and-names", + "exam-trial_midterm-20-w1-objects-and-names", + "exam-trial_midterm-21-w1-objects-and-names", + "exam-trial_midterm-22-w1-objects-and-names", + "exam-trial_midterm-24-w1-objects-and-names", + "exam-trial_midterm-7-w1-objects-and-names", + "exam-trial_midterm-9-w1-objects-and-names", + "kp-6-d2", + "kp-9", + "kp-manual-aliasing-copy", + "kp-manual-aliasing-copy-d1", + "ks-0153de2f70", + "ks-03c874b8bb", + "ks-419e787b39", + "ks-61c5deec4a", + "ks-685cd3d828", + "ks-6f41148083", + "ks-95be7f9418", + "ks-be78ccac04", + "ks-c0135e2a4a", + "ks-c815ffe1d5", + "ks-cb3a9e3fd2", + "ks-d79a1899f6", + "ks-df3b849d59", + "ks-e88d0a8060" + ] + }, + { + "week": 6, + "top1_unique_snippets": 8, + "top3_unique_snippets": 13, + "minimal_set_unique_snippets": 14, + "minimal_set_unused_snippets": 50, + "unused_snippet_ids": [ + "ai-example-1", + "ai-example-2", + "ai-example-3", + "ai-example-4", + "ai-example-5", + "ai-example-6", + "ai-example-7", + "ai-example-8", + "cs-905c77e1f3", + "kp-1", + "kp-1-d1", + "kp-2-d1", + "kp-3", + "kp-3-d1", + "kp-4-d1", + "kp-5", + "kp-5-d1", + "kp-6", + "kp-6-d1", + "kp-7", + "kp-7-d1", + "kp-8", + "kp-8-d1", + "kp-manual-datetime-day-of-year", + "kp-manual-datetime-delta", + "kp-manual-datetime-format", + "kp-manual-datetime-iso", + "kp-manual-datetime-now", + "kp-manual-datetime-replace", + "ks-0a4fcae36d", + "ks-0e5c8b8b42", + "ks-169cc25be1", + "ks-1bc815f6d1", + "ks-3e04c4d5e8", + "ks-662456da41", + "ks-72c58bb6b2", + "ks-900b394f8e", + "ks-b9d93f2bc1", + "ks-cacc4fbc21", + "ks-cd030b9520", + "ks-dd2965ef50", + "ks-e643ee5e77", + "manual-datetime-delta", + "manual-datetime-iso", + "manual-datetime-overlap", + "manual-datetime-replace", + "manual-datetime-strftime-loop", + "manual-day-of-year", + "manual-strftime-vs-strptime", + "manual-timedelta-attrs" + ] + }, + { + "week": 4, + "top1_unique_snippets": 7, + "top3_unique_snippets": 13, + "minimal_set_unique_snippets": 11, + "minimal_set_unused_snippets": 37, + "unused_snippet_ids": [ + "aiq-6", + "cs-0d319e4faf", + "cs-14245b8c1f", + "cs-30e53467b8", + "cs-e7bc165499", + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "kp-manual-init-defaults", + "kp-manual-init-defaults-d1", + "kp-manual-string-method-results", + "kp-manual-string-method-results-d1", + "ks-2c73fabc68", + "ks-309158a68c", + "ks-40d373c410", + "ks-45aead894c", + "ks-5198d93ec1", + "ks-5cbba26b09", + "ks-72dda5450c", + "ks-acb7f400b2", + "ks-b734a22f46", + "ks-bdea67862f", + "ks-cdb152720e", + "ks-e4dc502d3e", + "ks-ea5a4acb43", + "ks-f80f1bf556", + "manual-find-vs-index", + "manual-method-call", + "manual-oop-attrs", + "manual-oop-constructor-defaults", + "manual-self", + "manual-string-escapes", + "manual-string-format-method", + "manual-string-immutability", + "manual-string-islower-method", + "manual-string-literals-example", + "manual-string-repetition" + ] + }, + { + "week": 5, + "top1_unique_snippets": 8, + "top3_unique_snippets": 9, + "minimal_set_unique_snippets": 9, + "minimal_set_unused_snippets": 47, + "unused_snippet_ids": [ + "cs-2e178eda82", + "cs-3d987070d4", + "cs-49cf15967e", + "cs-82ef14b9d5", + "cs-8bae99d6de", + "cs-8ec741987c", + "cs-b069af91f4", + "cs-b3e0b57d7a", + "cs-c4c296595e", + "cs-cdfd529b3d", + "cs-e6b6bd65f0", + "kp-1-d2", + "kp-manual-df-constructor", + "kp-manual-drop-missing", + "kp-manual-drop-missing-d1", + "kp-manual-drop-missing-d2", + "kp-manual-series-default-index", + "kp-manual-series-vs-df", + "ks-0114a2cff0", + "ks-052ed25923", + "ks-0d2d15f8d2", + "ks-115ab52188", + "ks-17e621a20d", + "ks-18a9645168", + "ks-21496ff1cd", + "ks-2bed6c308f", + "ks-305a41a33e", + "ks-57ff66f9f1", + "ks-591dd1aa33", + "ks-75cf35c8b4", + "ks-99fe849762", + "ks-9a5d2c05fb", + "ks-dfc064979d", + "ks-f1be187b50", + "ks-f550a3ffc7", + "ks-f8eec928e1", + "manual-df-constructor", + "manual-pandas-df", + "manual-pandas-import", + "manual-pandas-map-column-sum", + "manual-pandas-select-shape", + "manual-pandas-series", + "manual-pandas-split-into-columns", + "manual-series-index", + "manual-series-vs-dataframe", + "manual-working-values-axis-apply", + "manual-working-values-string-vs-map" + ] + } + ], + "recommendations": { + "review_high_priority_themes_first": [ + "Strings, Indexing, and Text Methods", + "Loops, Iteration, and Comprehensions", + "Functions, Returns, and Scope" + ], + "hold_off_on_implementation_until_human_review": true, + "likely_first_pass_focus": [ + "Strings, Indexing, and Text Methods", + "Loops, Iteration, and Comprehensions", + "Functions, Returns, and Scope", + "Dictionaries, Tuples, and Sets", + "OOP, self, and Attributes" + ] + } +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/review_packets/round1.md b/data/vision_exam_pipeline/review_packets/round1.md new file mode 100644 index 0000000..f43caef --- /dev/null +++ b/data/vision_exam_pipeline/review_packets/round1.md @@ -0,0 +1,175 @@ +# Review Packet (round1) + +## What Needs Your Review + +- This packet condenses the round-1 synthesis into review themes instead of 151 isolated suggestions. +- The goal is to decide which snippet edits/additions are worth implementing before the second evaluation round. +- Completed evaluations: `168` +- Answerability split: `certain=88`, `partial=40`, `insufficient=40` + +## Recommended Review Order + +1. **Strings, Indexing, and Text Methods** (`priority=high`, `questions=52`, `suggestions=70`, `direction=add_this`) +2. **Loops, Iteration, and Comprehensions** (`priority=high`, `questions=14`, `suggestions=19`, `direction=add_this`) +3. **Functions, Returns, and Scope** (`priority=high`, `questions=11`, `suggestions=31`, `direction=add_this`) +4. **Dictionaries, Tuples, and Sets** (`priority=medium`, `questions=2`, `suggestions=6`, `direction=add_this`) +5. **OOP, self, and Attributes** (`priority=medium`, `questions=1`, `suggestions=7`, `direction=add_this`) +6. **Operators and Boolean Logic** (`priority=medium`, `questions=0`, `suggestions=7`, `direction=add_this`) +7. **Pandas Core Operations** (`priority=medium`, `questions=0`, `suggestions=7`, `direction=add_this`) +8. **Miscellaneous Exam-Specific Gaps** (`priority=selective`, `questions=0`, `suggestions=3`, `direction=add_this`) +9. **Datetime and Timedelta** (`priority=selective`, `questions=0`, `suggestions=1`, `direction=add_this`) + +## Priority Themes + +### Strings, Indexing, and Text Methods + +- Priority: `high` +- Affected questions: `52` (`partial=19`, `insufficient=33`) +- Related synthesized suggestions: `70` +- Suggested direction mix: `{'add_this': 70}` +- Representative gaps: + - The snippets lack a clear explanation of the difference between label-based (.loc) and integer-position-based (.iloc) indexing, specifically regarding the inclusivity of the stop index. + - The snippets provide zero explanation for Pandas-specific method syntax required to evaluate the options. + - The snippets lack a clear example of dictionary comprehension syntax and the specific use of slicing [:-1] to remove a trailing character in a list context. +- Representative suggestions: + - Key Point: Boolean String Methods. Methods like .islower(), .isupper(), and .isdigit() return True only if the string contains at least one character and all characters meet the criteria. Importantly, .islower() returns False for spaces, punctuation, and numbers as they are not lowercase letters. + - Create a common question snippet: 'How do zip() and floor division (//) work?'. Content: `zip(list1, list2)` pairs elements by index: (list1[0], list2[0]), (list1[1], list2[1]). `//` is floor division, which divides and rounds down to the whole number (e.g., 5 // 2 = 2). + - Expand the search text/explanation to explicitly define why option A ([::-2][::-1]) results in [2, 4, 6, 8, 10] (it reverses the reversed slice). + +### Loops, Iteration, and Comprehensions + +- Priority: `high` +- Affected questions: `14` (`partial=10`, `insufficient=4`) +- Related synthesized suggestions: `19` +- Suggested direction mix: `{'add_this': 19}` +- Representative gaps: + - The main conceptual hurdle is the implicit conversion of Booleans to integers during a sum operation, and the behavior of an empty match (summing all False values). + - The main missing piece is a clear explanation of how range(start, stop) behaves regarding the upper bound. + - There is a complete lack of 'lambda' syntax explanation in the recommended snippets. +- Representative suggestions: + - Create a 'Comprehension Syntax' summary card: 1. Dictionary: {key: value for item in iterable}, 2. List: [value for item in iterable], 3. Set: {value for item in iterable}. + - List Comprehension: [expression for item in iterable] creates a new list by running the expression for every item. Example: [i*2 for i in range(3)] generates [0, 2, 4]. + - Create a snippet explaining the range() function: range(0, 10) produces numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The number 10 is not included. + +### Functions, Returns, and Scope + +- Priority: `high` +- Affected questions: `11` (`partial=9`, `insufficient=2`) +- Related synthesized suggestions: `31` +- Suggested direction mix: `{'add_this': 27, 'consider_instead': 4}` +- Representative gaps: + - Existing snippets provide the 'what' (rules) and the 'where' (class), but miss the 'why' regarding the logical structure of comparison functions. + - Existing snippets cover the 'how' for the correct options but don't explicitly warn against the common mistake of passing a Series into .map(). + - The primary gap is the 'implicit return' behavior. A student can deduce x=0 and see that neither 'if x > 0' nor 'if x < 0' will run, but they won't know what happens when a function 'runs out' of code. +- Representative suggestions: + - Title: 'Comparing Objects with Multiple Criteria'. Snippet: 'When comparing two objects (A, B) based on multiple rules, remember that ! (A > B) does not imply (B > A). Example: def compare(self, other): if self.val > other.val and self.count >= other.count: return self; if other.val > self.val and other.count >= self.count: return other; return None' + - Create a snippet titled 'Conditional Expressions vs Statements' showing: 'return "Yes" if check else "No"' is equivalent to 'if check: return "Yes" else: return "No"'. + - Add a compare method: def is_better(self, other): return self.average() > other.average() + +### Dictionaries, Tuples, and Sets + +- Priority: `medium` +- Affected questions: `2` (`partial=1`, `insufficient=1`) +- Related synthesized suggestions: `6` +- Suggested direction mix: `{'add_this': 6}` +- Representative gaps: + - Missing the specific rule that Python dictionaries compare equal if they have the same key-value pairs, regardless of order. + - The primary gaps are the mathematical syntax for parity checking and exponentiation, as well as the explicit distinction between integer accumulation and list appending. +- Representative suggestions: + - Create a 'Sequence Properties' card showing that len([]) == 0, len({}) == 0, and len('') == 0, and explaining that a == b == c is only True if all three are identical. + - Add a snippet explaining 'Sorted Dictionary Iteration': 'To process a dictionary in order of its keys, use `for key in sorted(my_dict.keys()):`. This ensures you visit keys from smallest to largest, which is useful for calculating running totals.' + - Create a snippet showing: 'for key in sorted(prices.keys()): ...' and another showing 'sub_total = sum([val for key, val in d.items() if key < 10])'. + +### OOP, self, and Attributes + +- Priority: `medium` +- Affected questions: `1` (`partial=1`, `insufficient=0`) +- Related synthesized suggestions: `7` +- Suggested direction mix: `{'consider_instead': 3, 'add_this': 4}` +- Representative gaps: + - No snippet explicitly demonstrates the difference between a method reference and a method call (e.g., self.rating vs self.rating()), nor does any snippet show one instance calling a method on another instance (other.rating()). +- Representative suggestions: + - Update the search_text to show a snippet of the code for the Vehicle class, specifically including a default value for the 'mode' attribute (e.g., mode='land'). + - Create a snippet explaining 'self' as a reference to the current instance, used to access attributes defined in __init__. + - Title: Instance Attributes and 'self'. Content: 'To make an attribute available on an object (like my_car.name), you must assign it to self inside the __init__ method (e.g., self.name = vehicle_name). Without self, the variable only exists temporarily during creation.' + +### Operators and Boolean Logic + +- Priority: `medium` +- Affected questions: `0` (`partial=0`, `insufficient=0`) +- Related synthesized suggestions: `7` +- Suggested direction mix: `{'consider_instead': 3, 'add_this': 4}` +- Representative suggestions: + - Ensure the 'search_text' includes the full code for options a and b and clarifies why both work, matching the provided question explanation. + - Create a snippet showing: 'my_list = [True, False]; len([]); my_list[0] # Returns True'. + - Snippet: Comparison Operators. x >= y means 'x is greater than or equal to y'. x < y means 'x is less than y'. Example: 0 >= 0 is True. + +### Pandas Core Operations + +- Priority: `medium` +- Affected questions: `0` (`partial=0`, `insufficient=0`) +- Related synthesized suggestions: `7` +- Suggested direction mix: `{'add_this': 6, 'consider_instead': 1}` +- Representative suggestions: + - Create a snippet titled 'Pandas Boolean Filtering' showing: df_filtered = df[df['Salary'] > 50000]. + - Ensure the example code includes a lambda with a condition, e.g., s.map(lambda x: 'High' if x > 10 else 'Low'). + - Create a snippet titled 'Lambda Basics' that explains: 'lambda x: x + 5' means 'take x and add 5 to it'. + +### Miscellaneous Exam-Specific Gaps + +- Priority: `selective` +- Affected questions: `0` (`partial=0`, `insufficient=0`) +- Related synthesized suggestions: `3` +- Suggested direction mix: `{'add_this': 3}` +- Representative suggestions: + - Add a snippet demonstrating: count = sum([val == target for val in collection]). Show that this results in an integer, even if the count is zero. + - Add a foundational snippet explaining that .loc[2:4] includes labels 2, 3, and 4, whereas .iloc[[3, 2, 1]] selects the 4th, 3rd, and 2nd rows respectively. + - Update the search_text to include the full solution code for option C: word_lengths = {word: len(word) for word in words}. + +### Datetime and Timedelta + +- Priority: `selective` +- Affected questions: `0` (`partial=0`, `insufficient=0`) +- Related synthesized suggestions: `1` +- Suggested direction mix: `{'add_this': 1}` +- Representative suggestions: + - Add a 'Topic Detail' or 'Cheat Sheet' item for Week 8 (Datetime) covering: 1. datetime(year, month, day, hour, minute) 2. timedelta(minutes=N) 3. Comparing datetimes using <, >, ==. + +## Strong Existing Snippets + +| Rank | Snippet | Best single | Top 3 | Minimal set | +|---|---|---:|---:|---:| +| 1 | `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`
Week 5 • Working With Values • recommended/source_exam | 10 | 20 | 18 | +| 2 | `exam-midterm_2023-14-w2-loops`
Week 2 • Loops • recommended/source_exam | 5 | 21 | 12 | +| 3 | `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`
Week 5 • Inspecting and Selecting Data • recommended/source_exam | 6 | 13 | 11 | +| 4 | `exam-Resit 22/23-7-w2-dictionaries-and-mappings`
Week 2 • Dictionaries and Mappings • recommended/source_exam | 4 | 21 | 10 | +| 5 | `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`
Week 5 • Pandas Core Structures • recommended/source_exam | 4 | 15 | 12 | +| 6 | `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`
Week 4 • OOP Fundamentals • recommended/source_exam | 7 | 11 | 9 | +| 7 | `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`
Week 4 • OOP Fundamentals • recommended/source_exam | 3 | 15 | 11 | +| 8 | `exam-extra_practice-9-w3-return-behavior`
Week 3 • Return Behavior • recommended/source_exam | 5 | 10 | 7 | +| 9 | `exam-intro_python_sample_final_24_25-10-w6-datetime`
Week 6 • Datetime • recommended/source_exam | 5 | 8 | 8 | +| 10 | `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`
Week 3 • Defining and Calling Functions • recommended/source_exam | 5 | 6 | 8 | +| 11 | `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`
Week 5 • Pandas Core Structures • recommended/source_exam | 2 | 11 | 7 | +| 12 | `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`
Week 2 • Dictionaries and Mappings • recommended/source_exam | 1 | 13 | 7 | +| 13 | `aiq-5`
Week 5 • Inspecting and Selecting Data • aiQuestions/ai_common_question | 3 | 8 | 6 | +| 14 | `exam-midterm_2023-9-w3-arguments`
Week 3 • Arguments • recommended/source_exam | 4 | 8 | 4 | +| 15 | `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`
Week 5 • Inspecting and Selecting Data • recommended/source_exam | 2 | 10 | 6 | + +## Week Coverage Snapshot + +| Week | Top 1 unique | Top 3 unique | Minimal-set unique | Minimal-set unused | +|---|---:|---:|---:|---:| +| 2 | 22 | 34 | 31 | 62 | +| 3 | 22 | 34 | 26 | 38 | +| 1 | 8 | 18 | 15 | 57 | +| 6 | 8 | 13 | 14 | 50 | +| 4 | 7 | 13 | 11 | 37 | +| 5 | 8 | 9 | 9 | 47 | + +## Suggested Human Workflow + +1. Review the high-priority themes first and decide `add`, `edit existing`, or `skip`. +2. Use the representative suggestions as examples, not as a forced one-to-one implementation list. +3. Favor additions/edits that solve multiple question gaps rather than single-exam edge cases. +4. Only after that review should the implementation round begin. + diff --git a/data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md b/data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md new file mode 100644 index 0000000..2972f40 --- /dev/null +++ b/data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md @@ -0,0 +1,424 @@ +# Round 1 Manual Review Packet + +This packet is a hand-synthesized review document based on: + +- `data/vision_exam_pipeline/synthesis/round1.json` +- `data/vision_exam_pipeline/evaluations/round1.json` +- `data/vision_exam_pipeline/analytics/round1.json` + +The goal is not to preserve all 151 raw suggestions. It is to collapse semantically duplicate edit/addition requests into decision-ready clusters for human review. + +## Current State + +- Completed question evaluations: `168 / 168` +- Answerable with certainty: `88` +- Partially answerable: `40` +- Insufficient with current snippets: `40` +- We are at the human review gate before any snippet/content implementation round. + +## Recommended Review Order + +1. Strings, slicing, formatting, and basic operators +2. Iteration helpers and comprehension syntax +3. Dictionary construction and iteration patterns +4. Pandas selection/indexing/filtering +5. Datetime parsing, formatting, and arithmetic +6. OOP fundamentals and comparison logic +7. Flexible function signatures, return semantics, and scope cleanup +8. Exact-match retrieval fixes for existing snippets + +## Deduplicated Recommendation Clusters + +### 1. Essential String Methods and Indexing Reference + +- Absorbs duplicate requests about `.split()`, `.join()`, `.replace()`, `.find()`, negative indexing, slicing, nested indexing, `.index()`, and reverse-step slicing. +- Representative raw asks include: + - `round1:12` + - `round1:84` + - `round1:96` + - `round1:103` + - `round1:104` + - `round1:132` +- Why it helps: + - This is the single biggest beginner-mechanics gap in the round-1 evaluations. + - It would directly reduce the large cluster of string-method and indexing questions that are currently partial or insufficient. + - It should replace many tiny string-specific additions with one reusable exam-oriented reference. +- Why it may not be necessary: + - Some exact-match exam snippets already solve the concrete questions if the user happens to find the right one. + - A very large card could become bloated if it tries to cover every string method. +- Suggested direction: `add` +- Preferred form: + - One compact card titled something like `Essential String Methods and Indexing` + - Include only exam-relevant primitives and 4-6 tiny examples + +### 2. Output Formatting and String Construction + +- Absorbs duplicate requests about f-strings, `.format()`, decimal formatting, list-to-sentence output, and cases where `join()` is not enough because the required output contains custom wording like `", and "`. +- Representative raw asks include: + - `round1:58` + - `round1:85` + - `round1:105` + - `round1:122` + - `round1:136` +- Why it helps: + - Several questions are not conceptually hard; they fail because the user cannot reconstruct the exact output format. + - One card would cover both beginner formatting syntax and common exam traps. +- Why it may not be necessary: + - There is overlap with the broader string-method cluster above. + - If space is tight, this could be merged into the same string card instead of becoming its own standalone item. +- Suggested direction: `add`, but merge into cluster 1 if density becomes a concern. + +### 3. Boolean String Predicates + +- Absorbs duplicate requests about `.islower()`, `.isupper()`, `.isdigit()`, and how punctuation/spaces affect those methods. +- Representative raw asks include: + - `round1:80` + - `round1:101` + - `round1:127` +- Why it helps: + - This exact gap appeared in repeated evaluations of the same style of question. + - It is especially useful for zero-knowledge users who cannot infer the non-letter behavior of these methods. +- Why it may not be necessary: + - This is too narrow to justify a standalone large card. + - It fits naturally as a sub-block inside the string reference. +- Suggested direction: `add`, but as a subsection of cluster 1, not as a separate standalone snippet. + +### 4. Iteration Helpers and Basic Operator Traps + +- Absorbs duplicate requests about `zip()`, `enumerate()`, membership with `in`, tuple unpacking in loops, `//`, `%`, and boolean-to-int counting with `sum(...)`. +- Representative raw asks include: + - `round1:10` + - `round1:22` + - `round1:26` + - `round1:50` + - `round1:54` + - `round1:70` + - `round1:81` + - `round1:102` + - `round1:131` + - `round1:149` +- Why it helps: + - This is one of the clearest duplicate families in the synthesis. + - The same mechanics recur across multiple exams and multiple weeks. + - A compact reference would make several currently-insufficient questions fully answerable. +- Why it may not be necessary: + - The operator half is slightly broader than the iteration half. + - If the card gets too wide, the operator notes could instead be added to an existing fundamentals key point. +- Suggested direction: `add` +- Preferred form: + - One card for `zip`, `enumerate`, tuple unpacking, and membership + - One small sidebar/subsection for `/` vs `//`, `%`, and boolean counting with `sum(...)` + +### 5. Comprehension Syntax Reference + +- Absorbs duplicate requests about list, dict, and set comprehensions; placement of `key: value`; filter-vs-transform syntax; and conditional expressions inside comprehensions. +- Representative raw asks include: + - `round1:23` + - `round1:28` + - `round1:49` + - `round1:126` + - `round1:129` + - `round1:143` + - `round1:147` +- Why it helps: + - Many questions are failing because the syntax is not recognized quickly enough. + - This is a high-yield addition because it unifies several repeated requests into one pattern card. +- Why it may not be necessary: + - Some comprehension questions already have direct-match exam snippets. + - A card that is too abstract could be less useful than a syntax table with tiny examples. +- Suggested direction: `add` + +### 6. Dictionary Construction and Iteration Patterns + +- Absorbs duplicate requests about dictionary comprehensions, `dict(zip(...))`, `.keys()`, `.values()`, `.items()`, sorted dictionary iteration, dictionary equality, and counting patterns. +- Representative raw asks include: + - `round1:16` + - `round1:19` + - `round1:76` + - `round1:79` + - `round1:97` + - `round1:99` + - `round1:130` + - `round1:148` + - `round1:150` +- Why it helps: + - The synthesis shows two superficially separate clusters here, but they are really one decision: users need a compact dictionary reference that covers both construction and iteration. + - This cluster spans exact-match retrieval fixes and genuine concept gaps. +- Why it may not be necessary: + - Some of these requests are already covered by strong existing exam snippets. + - If we overbuild this, it may become a generic Python dictionary page rather than an exam tool. +- Suggested direction: `add` +- Preferred form: + - Focus on exam mechanics only: comprehension template, `dict(zip(...))`, `.keys/.values/.items`, `sum(d.values())`, equality ignoring insertion order, and sorted traversal + +### 7. Pandas Selection and Indexing Rules + +- Absorbs duplicate requests about `df['col']`, `df[['col1', 'col2']]`, `.loc`, `.iloc`, boolean masks, row/column selection, and invalid indexing forms like `df[row, col]`. +- Representative raw asks include: + - `round1:6` + - `round1:35` + - `round1:59` + - `round1:89` + - `round1:111` + - `round1:139` +- Why it helps: + - This is the clearest Pandas gap in the evaluation set. + - Several currently-insufficient questions would become much easier with one rule-based card. +- Why it may not be necessary: + - Week 5 already has some very strong exact-match snippets. + - A weak generic Pandas card could duplicate those without improving retrieval. +- Suggested direction: `add` +- Preferred form: + - A strict, example-heavy “valid vs invalid” indexing reference + +### 8. Pandas Filtering, Aggregation, and Column Arithmetic + +- Absorbs duplicate requests about boolean filtering, `mean()`, `sum()`, `count()`, `sort_values`, and row-wise column arithmetic like `df['C'] = df['A'] + df['B']` or subtraction. +- Representative raw asks include: + - `round1:5` + - `round1:7` + - `round1:65` + - `round1:93` + - `round1:95` + - `round1:137` +- Why it helps: + - This is another recurring Pandas failure mode, especially for students with no prior intuition for vectorized column operations. + - It complements cluster 7 cleanly. +- Why it may not be necessary: + - Some of the strongest existing snippets in the whole dataset are already Week 5 Pandas source exams. + - This may be better as an edit/expansion of existing high-performing Pandas snippets instead of a wholly new card. +- Suggested direction: `consider add`, leaning `edit existing` if you want to stay lean. + +### 9. Lambda, `map`, and `apply` + +- Absorbs duplicate requests about what `lambda x` means, how `.map()` differs from passing a precomputed Series, and when `apply(..., axis=1)` is needed. +- Representative raw asks include: + - `round1:4` + - `round1:21` + - `round1:41` + - `round1:66` + - `round1:94` + - `round1:119` +- Why it helps: + - This is a genuine conceptual gap and repeatedly appears in both Pandas and non-Pandas forms. + - One compact card would be much better than multiple micro-snippets. +- Why it may not be necessary: + - If added, it should be tightly scoped. A generic lambda tutorial would be too broad for the cheat sheet. + - Some of this could be absorbed into existing Week 5 Pandas examples. +- Suggested direction: `add` + +### 10. Datetime Parse/Format Cheat Sheet + +- Absorbs duplicate requests about `datetime(...)`, `strptime`, `strftime`, and format-code references such as `%Y`, `%m`, `%d`, `%H`, and `%M`. +- Representative raw asks include: + - `round1:11` + - `round1:36` + - `round1:60` + - `round1:88` + - `round1:92` + - `round1:110` + - `round1:116` + - `round1:124` + - `round1:125` + - `round1:141` +- Why it helps: + - Datetime requests are heavily duplicated and mostly point to one missing artifact: a compact parse/format reference. + - This is one of the cleanest “many duplicate requests, one right addition” clusters in the whole review. +- Why it may not be necessary: + - None of the individual asks need to be implemented separately if this one cheat sheet exists. + - It only becomes unnecessary if the existing Week 6 content is already sufficient for the intended exam style, which the evaluations suggest it is not. +- Suggested direction: `add` + +### 11. Datetime Object-vs-String Arithmetic + +- Absorbs duplicate requests about `timedelta`, adding minutes/days, extracting day/month/year, and the crucial distinction that `strptime` returns a datetime object while `strftime` returns a string. +- Representative raw asks include: + - `round1:42` + - `round1:43` + - `round1:67` + - `round1:69` + - `round1:91` + - `round1:115` + - `round1:142` +- Why it helps: + - Several round-1 failures are not about formatting codes; they are about reasoning with datetime objects after parsing. + - This is a separate conceptual cluster from parse/format syntax. +- Why it may not be necessary: + - If the parse/format cheat sheet is carefully designed, much of this can be embedded there instead of creating a second large datetime card. +- Suggested direction: `add`, but preferably as part 2 of the same datetime reference family rather than a disconnected standalone card. + +### 12. OOP Fundamentals: `self`, `__init__`, Attributes, and Defaults + +- Absorbs duplicate requests about assigning to `self`, default constructor arguments, calculated attributes, and instance attribute access. +- Representative raw asks include: + - `round1:37` + - `round1:61` + - `round1:87` + - `round1:109` + - `round1:113` + - `round1:120` + - `round1:134` +- Why it helps: + - The evaluations repeatedly show that users can often piece together OOP answers only by combining several snippets. + - One canonical OOP fundamentals card would reduce that fragmentation. +- Why it may not be necessary: + - There are already multiple strong OOP snippets in Week 4. + - A new card should replace duplication, not add yet another OOP variant. +- Suggested direction: `add` + +### 13. OOP Comparison Logic + +- Absorbs duplicate requests about comparison methods, asymmetric criteria, and returning `None` when neither object clearly wins. +- Representative raw asks include: + - `round1:1` + - `round1:90` + - `round1:112` + - `round1:114` +- Why it helps: + - This is a real gap, especially in the 2022 final Book comparison question family. +- Why it may not be necessary: + - There is already a strong existing comparison-oriented snippet (`manual-oop-state-compare`) and a strong exam snippet around comparing books. + - This feels more like an expansion of current content than a net-new concept family. +- Suggested direction: `edit existing` +- Preferred approach: + - Expand the strongest existing OOP comparison item with explicit asymmetric logic and the `None` case + +### 14. Flexible Arguments, Returns, and `kwargs` + +- Absorbs duplicate requests about `*args`, `**kwargs`, `.keys()/.values()`, tuple returns, and flexible-argument helper functions. +- Representative raw asks include: + - `round1:19` + - `round1:33` + - `round1:57` + - `round1:76` + - `round1:77` + - `round1:151` +- Why it helps: + - This cluster appears across return-behavior and function-signature questions, not just one exam. +- Why it may not be necessary: + - Some of these are quite specific to individual questions and could bloat the function material. + - The highest-value version is probably a compact “function signatures and returns” block rather than multiple separate additions. +- Suggested direction: `add`, but keep it compact. + +### 15. Return-Value and Scope Cleanup + +- Absorbs duplicate requests about implicit `None`, in-place methods returning `None`, and nested/local/global scope clarification. +- Representative raw asks include: + - `round1:3` + - `round1:14` + - `round1:31` + - `round1:47` + - `round1:74` +- Why it helps: + - These are real beginner traps that appear across multiple topics. +- Why it may not be necessary: + - The scope part is already almost covered. + - The return-value part may be better handled by strengthening existing fundamentals content rather than adding new standalone snippets. +- Suggested direction: `edit existing` + +### 16. Exact-Match Retrieval Fixes + +- Absorbs duplicate requests that are not new concept gaps, but fixes to existing snippets whose `search_text`, explanation, or option traces are incomplete or misleading. +- Representative raw asks include: + - `round1:27` + - `round1:48` + - `round1:77` + - `round1:96` + - `round1:97` + - `round1:98` + - `round1:100` + - `round1:103` + - `round1:109` + - `round1:145` +- Why it helps: + - This directly improves retrieval quality of already-valuable snippets. + - It is especially important because the strongest existing snippets are mostly `source_exam` items. +- Why it may not be necessary: + - These edits do not increase conceptual coverage by themselves. + - They should come after the higher-value conceptual additions are reviewed. +- Suggested direction: `edit existing` + +## Suggested First-Pass Decisions + +If we want a practical round-2 implementation list, the highest-value shortlist is: + +1. Add `Essential String Methods and Indexing` +2. Add `Iteration Helpers and Basic Operator Traps` +3. Add `Comprehension Syntax Reference` +4. Add `Dictionary Construction and Iteration Patterns` +5. Add `Pandas Selection and Indexing Rules` +6. Add `Datetime Parse/Format Cheat Sheet` +7. Add `OOP Fundamentals` +8. Edit the strongest existing OOP comparison snippet instead of adding a new comparison card +9. Edit existing fundamentals content for return-value traps and scope notes +10. Fix truncated or misleading exact-match `search_text` / explanation fields + +## Likely Skip or Absorb + +- Skip separate standalone file-handling work in this round. + - No meaningful file-handling cluster emerged from round 1. +- Skip separate tiny OOP worked examples. + - Best absorbed into the main OOP fundamentals card. +- Skip a standalone boolean-string-methods card. + - Best absorbed into the main strings reference. + +## Existing High-Value Snippets Worth Preserving + +These are the strongest existing anchors in the current data and should be treated as “do not accidentally dilute” items during the next round: + +1. `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals` + - Week 5, topic `Working With Values` + - Best single: `10`, Top 3: `20`, Minimal set: `18` + - Strongest overall snippet in the dataset right now + +2. `exam-midterm_2023-14-w2-loops` + - Week 2, topic `Loops` + - Best single: `5`, Top 3: `21`, Minimal set: `12` + +3. `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods` + - Week 5, topic `Inspecting and Selecting Data` + - Best single: `6`, Top 3: `13`, Minimal set: `11` + +4. `exam-Resit 22/23-7-w2-dictionaries-and-mappings` + - Week 2, topic `Dictionaries and Mappings` + - Best single: `4`, Top 3: `21`, Minimal set: `10` + +5. `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals` + - Week 5, topic `Pandas Core Structures` + - Best single: `4`, Top 3: `15`, Minimal set: `12` + +6. `exam-Test Exam 07-06-22-2-w4-oop-fundamentals` + - Week 4, topic `OOP Fundamentals` + - Best single: `7`, Top 3: `11`, Minimal set: `9` + +7. `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals` + - Week 4, topic `OOP Fundamentals` + - Best single: `3`, Top 3: `15`, Minimal set: `11` + +8. `exam-intro_python_sample_final_24_25-10-w6-datetime` + - Week 6, topic `Datetime` + - Best single: `5`, Top 3: `8`, Minimal set: `8` + +## Week-Level Signals for Later Ranking Work + +- Week 5 is the most concentrated high-value week. + - Only a small number of Pandas snippets are doing most of the real exam work. +- Weeks 4 and 6 are also fairly concentrated. + - Good candidates for meaningful leaderboard pages later. +- Weeks 1 and 2 have a large unused tail. + - Good candidates for future pruning or stricter recommended/additional separation. +- The strongest items are overwhelmingly `source_exam` snippets. + - That suggests future “highest value” logic should not assume key points or manual snippets naturally outrank exam-like examples. + +## Human Review Questions + +Before implementation, decide: + +1. Do we want a lean round-2 focused on the top 6-8 clusters only, or a broader round that also includes function-signature cleanup? +2. For Pandas, do we prefer: + - one new indexing card plus edits to existing high-performing snippets + - or two new cards: indexing and filtering/aggregation +3. For datetime, do we prefer: + - one dense combined datetime reference + - or two smaller cards: parse/format and arithmetic/object-vs-string +4. For OOP comparison logic, do we agree that `edit existing` is better than adding another comparison snippet? diff --git a/data/vision_exam_pipeline/selectable_items_snapshot.json b/data/vision_exam_pipeline/selectable_items_snapshot.json new file mode 100644 index 0000000..3ef1ddc --- /dev/null +++ b/data/vision_exam_pipeline/selectable_items_snapshot.json @@ -0,0 +1,8990 @@ +[ + { + "item_id": "manual-comments", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do comments start, and what does Python ignore after `#`?\nEverything after `#` on that logical line is ignored by Python.\nx = 3 # this comment does not execute\nprint(x)", + "week": 1 + }, + { + "item_id": "manual-logical-lines", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How can one logical line span multiple physical lines?\nUse open brackets or an explicit backslash to continue a statement across lines.\nnumbers = [\n 1,\n 2,\n 3,\n]", + "week": 1 + }, + { + "item_id": "kp-1", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "w1-python-basics-execution-model", + "subtopic_title": "Execution Model, Logical Lines, and Comments", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Python script is translated line by line into byte code, then byte code is translated into machine code. Writing code must be precise; ambiguities that humans handle fine will cause Python errors.", + "week": 1 + }, + { + "item_id": "ai-example-1", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "w1-python-basics-execution-model", + "subtopic_title": "Execution Model, Logical Lines, and Comments", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "print('Hello World') # Everything after the hashtag is a comment\nprint('Hello World') # Everything after the hashtag is a comment\nHello World", + "week": 1 + }, + { + "item_id": "ai-example-2", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "w1-python-basics-execution-model", + "subtopic_title": "Execution Model, Logical Lines, and Comments", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "print(_, __, ___)\n#\nprint(_, __, ___)", + "week": 1 + }, + { + "item_id": "ai-example-3", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "w1-python-basics-execution-model", + "subtopic_title": "Execution Model, Logical Lines, and Comments", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "print('Hello World')\nprint('Hello World')", + "week": 1 + }, + { + "item_id": "ai-example-4", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "w1-python-basics-execution-model", + "subtopic_title": "Execution Model, Logical Lines, and Comments", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "print(r\"This gives no \\\" error\")\n#\nprint(r\"This gives no \\\" error\")\nprint(r'This gives no \\' error')", + "week": 1 + }, + { + "item_id": "ai-example-5", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "w1-python-basics-execution-model", + "subtopic_title": "Execution Model, Logical Lines, and Comments", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "line_joining\na = 'Two or more physical lines can be joined' +\\\n ' with the help of backward slashes'\nprint(a)", + "week": 1 + }, + { + "item_id": "ai-example-6", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "w1-python-basics-execution-model", + "subtopic_title": "Execution Model, Logical Lines, and Comments", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "line_joining\na = ['Two or more physical lines can be joined', \n ' with the help of backward slashes']\nprint(a)", + "week": 1 + }, + { + "item_id": "ks-95be7f9418", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Python execution model\nPython script is translated line by line into byte code, then byte code is translated into machine code. Writing code must be precise; ambiguities that humans handle fine will cause Python errors.", + "week": 1 + }, + { + "item_id": "cs-09e2b215ee", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "print('Hello World') # Everything after the hashtag is a comment\nprint('Hello World') # Everything after the hashtag is a comment\nHello World", + "week": 1 + }, + { + "item_id": "cs-814a07a136", + "card_id": "w1-python-basics", + "topic": "Python Basics", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "123*1\n#\n123*1", + "week": 1 + }, + { + "item_id": "aiq-1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types.\nI is correct (e.g. a=1, b=2, both int). II is incorrect — if two objects have the same value they must have the same type.\nObjects/types", + "week": 1 + }, + { + "item_id": "aiq-2", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names", + "week": 1 + }, + { + "item_id": "aiq-3", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should prints:\n[1, 4, 16, 64].\nA mylist = []\nfor i in x:\nmylist[i] = x[i]**2\nprint(mylist)\nB mylist = [0] * len(x)\nfor i in range(len(x)):\nmylist[i] = x[i]**2\nprint(mylist)", + "week": 1 + }, + { + "item_id": "aiq-4", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, factor=3)\nmultiply(3, 4)\nmultiply()\nA def multiply(*args, factor=2):\ntotal = args[0]", + "week": 1 + }, + { + "item_id": "aiq-5", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True", + "week": 1 + }, + { + "item_id": "aiq-6", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy", + "week": 1 + }, + { + "item_id": "aiq-7", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function", + "week": 1 + }, + { + "item_id": "kp-1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Each object has identity, type, and value. Names bind to objects; rebinding changes the name, while in-place changes only affect mutable objects.", + "week": 1 + }, + { + "item_id": "kp-2", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Immutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the same object.", + "week": 1 + }, + { + "item_id": "kp-2-d1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "List is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]", + "week": 1 + }, + { + "item_id": "kp-2-d2", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Tuple is immutable — assigning to index raises TypeError\nt1 = (1, 2, 3)\nt1[2] = 4\n# TypeError: 'tuple' object does not support item assignment", + "week": 1 + }, + { + "item_id": "kp-3", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Assignment binds the left-hand name to the object produced on the right-hand side.", + "week": 1 + }, + { + "item_id": "kp-3-d1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Basic assignment\nname_1 = 300\nprint(name_1) # 300\nprint(type(name_1)) # \nprint(id(name_1)) # some unique integer", + "week": 1 + }, + { + "item_id": "kp-3-d2", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Two names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True", + "week": 1 + }, + { + "item_id": "kp-4", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Core built-in types: `int`, `float`, `str`, `bool`, `tuple`, `list`, `dict`, `set`.", + "week": 1 + }, + { + "item_id": "kp-4-d1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "All 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # list\nvar_7 = {'k1': 'v1'} # dict\nvar_8 = {123, '123'} # set", + "week": 1 + }, + { + "item_id": "kp-5", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Names can consist of letters (upper/lower), digits, and underscores. Names CANNOT start with a digit. Names ARE case-sensitive (name_1 != Name_1). Avoid Python reserved words (e.g., don't name a variable 'sorted', 'list', 'print').", + "week": 1 + }, + { + "item_id": "kp-6", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Syntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.", + "week": 1 + }, + { + "item_id": "kp-6-d1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Basic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]", + "week": 1 + }, + { + "item_id": "kp-6-d2", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Negative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)", + "week": 1 + }, + { + "item_id": "kp-manual-aliasing-copy", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "For mutable objects, `l2 = l1` aliases the same object; use slicing like `l1[:]` when you need an independent copy.", + "week": 1 + }, + { + "item_id": "kp-manual-aliasing-copy-d1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Aliasing vs slicing copy\nl1 = [1, 2, 3]\nl2 = l1\nl3 = l1[:]\nl1[0] = 99\nprint(l2) # [99, 2, 3]\nprint(l3) # [1, 2, 3]", + "week": 1 + }, + { + "item_id": "kp-7", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Functions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects.", + "week": 1 + }, + { + "item_id": "kp-7-d1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Simple function\ndef size(length, width):\n return length * width\nprint(size(2,3)) # 6", + "week": 1 + }, + { + "item_id": "kp-8", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Which code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others.", + "week": 1 + }, + { + "item_id": "kp-9", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Everything in Python is an object. Objects in Python have one id, one value, one type, and zero or more names An assignment statement is one of the ways to create an object. An object created with an assignment statement will have a name, an id, a value and a type.", + "week": 1 + }, + { + "item_id": "ai-example-1", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "List is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]\nImmutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the same object.", + "week": 1 + }, + { + "item_id": "ai-example-2", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Tuple is immutable — assigning to index raises TypeError\nt1 = (1, 2, 3)\nt1[2] = 4\n# TypeError: 'tuple' object does not support item assignment\nImmutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the same object.", + "week": 1 + }, + { + "item_id": "ai-example-3", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Basic assignment\nname_1 = 300\nprint(name_1) # 300\nprint(type(name_1)) # \nprint(id(name_1)) # some unique integer\nAssignment binds the left-hand name to the object produced on the right-hand side.", + "week": 1 + }, + { + "item_id": "ai-example-4", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Two names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True\nAssignment binds the left-hand name to the object produced on the right-hand side.", + "week": 1 + }, + { + "item_id": "ai-example-5", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "All 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # list\nvar_7 = {'k1': 'v1'} # dict\nvar_8 = {123, '123'} # set\nCore built-in types: `int`, `float`, `str`, `bool`, `tuple`, `list`, `dict`, `set`.", + "week": 1 + }, + { + "item_id": "ai-example-6", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Basic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.", + "week": 1 + }, + { + "item_id": "ai-example-7", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Negative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.", + "week": 1 + }, + { + "item_id": "manual-objects-aliasing", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Aliasing vs slicing copy\nl1 = [1, 2, 3]\nl2 = l1\nl3 = l1[:]\nl1[0] = 99\nprint(l2) # [99, 2, 3]\nprint(l3) # [1, 2, 3]\nFor mutable objects, `l2 = l1` aliases the same object; use slicing like `l1[:]` when you need an independent copy.", + "week": 1 + }, + { + "item_id": "ai-example-8", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "w1-objects-and-names-core", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Simple function\ndef size(length, width):\n return length * width\nprint(size(2,3)) # 6\nFunctions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects.", + "week": 1 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)\nA\nB\nC\nD\nA\n'3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is False. x == y == z evaluates as (x == y) and (y == z), which is False and True, resulting in False.", + "week": 1 + }, + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers between 0 and 10.", + "week": 1 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned.", + "week": 1 + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\nIf they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?\na\nb\nc\nd\na\nOption A correctly checks if destination is in the list 'europe' using the 'in' operator, and uses 'print' as requested. Option B uses 'return' which is only valid inside a function, and the prompt doesn't mention a function. Option C uses an assignment operator '=' instead of '==' and iterates incorrectly. Option D iterates incorrectly and uses 'return'.", + "week": 1 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\n\nFor example, if\nstudents = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 7.5.\nBernard has received a grade of 8.0.\n\nWhich of the following code segments will achieve what you want?\na\nb\nc\nd\na\nOption A correctly iterates over the list of dictionaries and uses f-strings with proper quote escaping (single quotes inside double quotes) and the `:.1f` format specifier to display the float to one decimal place.", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, factor=3)\nmultiply(3, 4)\nmultiply()\nA def multiply(*args, factor=2):\ntotal = args[0]\nfor num in args:\ntotal *= num\nreturn total * factor\nB def multiply(*args, factor=2):\nif not args:\nreturn 0\ntotal = args[0]\nfor num in args[1:]:\ntotal *= num\nreturn total * factor\nC Both functions will return the same values.\nD Neither functions will return the same values.", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-7-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called dict_keys that checks whether a certain key is in available in a certain dictionary.", + "week": 1 + }, + { + "item_id": "ks-e88d0a8060", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Objects: core properties\nEvery object has exactly one unique id (cannot change), exactly one type (cannot change), and exactly one value. The type defines what value can be stored and whether the value is mutable or immutable. An object can have zero, one, or more names bound to it. A name can only refer to one object at any time.", + "week": 1 + }, + { + "item_id": "ks-eae9bf47dd", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Mutable vs immutable types\nImmutable: int, float, str, bool, tuple. Mutable: list, dict, set. The value of a mutable object CAN be changed in-place. The value of an immutable object CANNOT be changed — a new object must be created.\nList is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]\nTuple is immutable — assigning to index raises TypeError\nt1 = (1, 2, 3)\nt1[2] = 4\n# TypeError: 'tuple' object does not support item assignment\nString reassignment creates a NEW object, not mutation\nbox_1 = 'content'\nold_id = id(box_1)\nbox_1 = 'new content'\nnew_id = id(box_1)\nprint(old_id == new_id) # False — different object", + "week": 1 + }, + { + "item_id": "ks-61c5deec4a", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assignment statements — reading right to left\nPython creates a new object with the value on the right, infers type from the value, then binds the name on the left to that object.\nBasic assignment\nname_1 = 300\nprint(name_1) # 300\nprint(type(name_1)) # \nprint(id(name_1)) # some unique integer\nTwo names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True\nTwo separate objects with equal value (different id)\nname_1 = 300\nname_2 = 300\nprint(name_1 == name_2) # True (same value)\nprint(id(name_1) != id(name_2)) # True (different objects)", + "week": 1 + }, + { + "item_id": "ks-cb3a9e3fd2", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Object types — the 8 types to know\nint, float, str, bool, tuple, list, dict, set\nAll 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # list\nvar_7 = {'k1': 'v1'} # dict\nvar_8 = {123, '123'} # set", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-9-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\nmylist = [1, 2, 5, 7, 9, 12]\nnew_list1 = mylist[0:3]\nnew_list2 = mylist[1:4]\nprint(new_list1 + new_list2)\nWhat will be printed?\nA [1, 2, 5, 7, 2, 5, 7, 9]\nB [1, 2, 5, 2, 5, 7]\nC [2, 5, 7, 5, 7, 9]\nD [2, 5, 5, 7]", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-11-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\nx = 10\ny = '5'\nz = x + y\n​What will be the value of 'z' and why?\nA The code will result in a None because 'x' and 'y' have different types.\nB The code will result in an error because you can't add an integer and a string together.\nC The value of z will be '105' because Python concatenates strings.\nD The value of z will be 15 because the string '5' will be implicitly converted to an integer.", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-12-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Which other program will produce the same output as the following code snippet?", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-14-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\na = 1\nb = 2.0\nc = '3'\nd = 'hello'\ny = {}\nfor i in [0,1]:\nif i==0:\nif type(a)==type(b):\ny[i] = True\nelse:\ny[i] = False\nif i==1:\nif type(c)==type(d):\ny[i] = True\nelse:\ny[i] = False\nprint(y)\nWhat will this code snippet print?\nA {0: 1, 1: 1}\nB {0: True, 1: True}\nC {0: 0, 1: 1}\nD {0: False, 1: True}", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor char in key:\nif char == character:\ncount += 1\ny[key] = count\nreturn y\nWhat would be returned by this function, if we call the function twice as follows:\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'], 'i')\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'])\nA {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 1, 'Julia': 1, 'Ian': 1, 'Noah': 1, 'Liam': 1, 'Anna': 1}\nB The first function call will result in an error because there are too many arguments.\nC The second function call will result in an error because there is a missing argument.\nD {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 0, 'Julia': 0, 'Ian': 0, 'Noah': 0, 'Liam': 0, 'Anna': 0}", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-16-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "What is the output of the program below?", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-18-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following function which take a list of numerical strings as an argument.", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-20-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "You have the following list:\nmy_list = [1,2,3,4]\nWhich one of the following lines of code lines does not print 4 as the output?\nA print(my_list[4])\nB print(my_list[-1])\nC print(max(my_list))\nD print(len(my_list))", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-21-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?\nA y = [1, 2, 3, 4]\nprint('b'+ max(y)*3)\nB print('b' + str(len(x)*3))\nC z = [[\"a\", \"b\", \"c\"], [1, 2, 3, 4]]\nprint(z[0][1] + str(z[1][3])*3)\nD print('b'+ str(8 % 4)*3)", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-22-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92.0, 98.0, 100.0],\n\"quizzes\": [82.0, 83.0, 91.0],\n\"tests\": [89.0, 97.0]},\n\"david\": {\"name\": \"David\",\n\"homework\": [0.0, 87.0, 75.0, 22.0],\n\"quizzes\": [0.0, 75.0, 78.0],\n\"tests\": [100.0, 100.0]}\n}\nYou want to create a function that calculates the average final course grade of a student.\nThe final course grade is calculated as 20% average homework grade, 10% average quizzes grade and 70% average tests\ngrade.\nWhich of the following programs will work as intended and will give the final course grade of Eva?\nA def average(numbers):\nreturn sum(numbers)/(len(numbers))\ndef final_average(student):\nhomework = average(student['homework'])\nquizzes = average(student['quizzes'])\ntests = average(student['tests'])\nreturn round(0.2*homework + 0.1*quizzes + 0.7*tests, 2)\nfinal_average(students[\"eva\"])\nB def final_average(student):\ndef average(numbers):\nreturn sum(numbers)/(len(numbers)\nhomework = average(student['homework'])\nq…", + "week": 1 + }, + { + "item_id": "exam-trial_midterm-24-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA The code will result in an error.\nB True\nC None\nD False\nEnd of test Trial Midterm - Introduction to Python - 23/24", + "week": 1 + }, + { + "item_id": "exam-midterm_2023-4-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Assume you have the following variables:\nx = 'abc'\ny = 3\nz = 2.0\nWhat will be printed after these lines of code?\nprint(x*y)\nprint(x*z)\nprint(y*z)\nA 'abcabcabc'\nThe code will result in a TypeError because you can't multiply a float and a string together.\n6.0\nB The code will result in a ValueError because you can't concatenate a string and an integer.\nThe code will result in a TypeError because you can't multiply a float and a string together.\n6\nC 'abcabcabc'\n'abcabc'\n6.0\nD 'abcabcabc'\nThe code will result in a TypeError because you can't multiply a float and a string together.\n6", + "week": 1 + }, + { + "item_id": "exam-midterm_2024-4-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\na = 1\nb = 2.0\nc = '3'\nd = 'hello'\ny = {}\nfor i in [0,1]:\nif i==0:\nif type(a)==type(b):\ny[i] = True\nelse:\ny[i] = False\nif i==1:\nif type(c)==type(d):\ny[i] = True\nelse:\ny[i] = False\nprint(y)\nWhat will this code snippet print?\nA {0: False, 1: True}\nB {0: True, 1: True}\nC {0: 0, 1: 1}\nD {0: 1, 1: 1}", + "week": 1 + }, + { + "item_id": "exam-midterm_2024-6-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\nx = 10\ny = '5'\nz = x + y\n​What will be the value of 'z' and why?\nA The value of z will be 15 because the string '5' will be implicitly converted to an integer.\nB The value of z will be '105' because Python concatenates strings.\nC The code will result in an error because you can't add an integer and a string together.\nD The code will result in a None because 'x' and 'y' have different types.", + "week": 1 + }, + { + "item_id": "exam-extra_practice-11-w1-objects-and-names", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "x = ['abc', [[]], (1, 2), {}, True, 3.0, 4]\n\nWhat is the output of the following code snippet?\n\nprint(type(float(x[2][0] + x[2][1])) == type(x[-2]))\na\nb\nc\nd\nd\nx[2] = (1,2). x[2][0]=1, x[2][1]=2. 1+2=3. float(3)=3.0. type(3.0)=float. x[-2]=3.0 (index 5). type(3.0)=float. float==float → True.", + "week": 1 + }, + { + "item_id": "ks-d79a1899f6", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Names / variable naming rules\nNames can consist of letters (upper/lower), digits, and underscores. Names CANNOT start with a digit. Names ARE case-sensitive (name_1 != Name_1). Avoid Python reserved words (e.g., don't name a variable 'sorted', 'list', 'print').", + "week": 1 + }, + { + "item_id": "ks-6f41148083", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Slicing\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.\nBasic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]\nNegative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)\nSlice reversal\nl1 = [1, 2, 3, 4]\nprint(l1[::-1]) # [4, 3, 2, 1]\nSlicing creates new object — key exam trap\nl1 = [1, 2, 3, 4]\nl2 = l1\nl3 = l1[:]\nl1[-1] = 5\nprint(l1 == l2, l2 == l3) # True False (l3 is independent copy)\nChanging a list slice vs index\nl1 = [1, 2, 3, 4, 5, 6]\nl1[1:2] = [1, 1] # replaces element at index 1 with two elements\nprint(l1) # [1, 1, 1, 3, 4, 5, 6]\n\nl1 = [1, 2, 3, 4, 5, 6]\nl1[1] = [1, 1] # replaces element at index 1 with a list\nprint(l1) # [1, [1, 1], 3, 4, 5, 6]\nSlicing strings and tuples\nt1 = (1, 2, 3)\nprint(t1[1:]) # (2, 3)\ns1 = 'uva Amsterdam'\nprint(s1[5:-3:2]) # 'mtr'\nChanging string/tuple (must create new object)\ns1 = 'uva Amsterdam'\n# s1[6] = 's' # ERROR\ns1 = s1[:6] + 's' + s1[7:]\nprint(s1) # works\n\nt1 = (1, 4, 3)\n# t1[1] = 2 # ERROR\nt1 = t1[:1] + (2,) + t1[2:]\nprint(t1) # works", + "week": 1 + }, + { + "item_id": "ks-0153de2f70", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Functions — basics\nFunctions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects.\nSimple function\ndef size(length, width):\n return length * width\nprint(size(2,3)) # 6", + "week": 1 + }, + { + "item_id": "ks-df3b849d59", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Exam question types\nWhich code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others. / Which correctly solves the problem? Options may include: 'None of the above', 'Both', 'All', 'An error'.", + "week": 1 + }, + { + "item_id": "ks-419e787b39", + "card_id": "w1-objects-and-names", + "topic": "Objects and Names", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "objects\n### Everything in Python is an object. Objects in Python have one id, one value, one type, and zero or more names\n
An assignment statement is one of the ways to create an object. An object created with an assignment statement will have a name, an id, a value and a type.\n
If you know the name you can ask for the id, the value, and the type", + "week": 1 + }, + { + "item_id": "aiq-1", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What is the result of (a//b)*b + a%b?\nArithmetic operators", + "week": 1 + }, + { + "item_id": "aiq-2", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Boolean operator precedence: not > and > or\na==1 or a==2 and b==1 or b==2 is evaluated as a==1 or (a==2 and b==1) or b==2", + "week": 1 + }, + { + "item_id": "kp-1", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "a+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b)*b + a%b == a always.", + "week": 1 + }, + { + "item_id": "kp-1-d1", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Floor division and modulo\nprint(5 // 3, 5 % 3) # 1 2\nprint(-5 // 3, -5 % 3) # -2 1\nprint(5 // 2, 5 % 2) # 2 1\nprint(-5 // 2, -5 % 2) # -3 1", + "week": 1 + }, + { + "item_id": "kp-2", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal;", + "week": 1 + }, + { + "item_id": "kp-2-d1", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Float precision issue\nprint(1.1 + 2.2 == 3.3) # False", + "week": 1 + }, + { + "item_id": "kp-2-d2", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "List/tuple comparison\nprint([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less)\nprint([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0)", + "week": 1 + }, + { + "item_id": "kp-3", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "x and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then 'or'. Use parentheses to avoid confusion.", + "week": 1 + }, + { + "item_id": "kp-3-d1", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Precedence trap\na=1; b=3\nprint(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter)\nprint((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT)", + "week": 1 + }, + { + "item_id": "ai-example-1", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Floor division and modulo\nprint(5 // 3, 5 % 3) # 1 2\nprint(-5 // 3, -5 % 3) # -2 1\nprint(5 // 2, 5 % 2) # 2 1\nprint(-5 // 2, -5 % 2) # -3 1\na+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b)*b + a%b == a always.", + "week": 1 + }, + { + "item_id": "ai-example-2", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Float precision issue\nprint(1.1 + 2.2 == 3.3) # False\n==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal;", + "week": 1 + }, + { + "item_id": "ai-example-3", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "List/tuple comparison\nprint([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less)\nprint([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0)\n==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal;", + "week": 1 + }, + { + "item_id": "ai-example-4", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Precedence trap\na=1; b=3\nprint(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter)\nprint((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT)\nx and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then 'or'. Use parentheses to avoid confusion.", + "week": 1 + }, + { + "item_id": "ai-example-5", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "arithmetic_operators\nprint(5//2, 5%2)\n2 1", + "week": 1 + }, + { + "item_id": "ai-example-6", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "arithmetic_operators\nprint(4 + 3)\nprint(4 - 3)\nprint(4 * 3)\nprint(4 / 3)\nprint(4 / 2)\nprint(4 ** 3)\n7\n1\n12\n1.3333333333333333\n2.0\n64", + "week": 1 + }, + { + "item_id": "ai-example-7", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "arithmetic_operators\nprint(5 // 3, 5 % 3)\nprint(-5 // 3, -5 % 3)\nprint(5 // 2, 5 % 2)\nprint(-5 // 2, -5 % 2)\n1 2\n-2 1\n2 1\n-3 1", + "week": 1 + }, + { + "item_id": "ai-example-8", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "w1-operators-and-truth-core", + "subtopic_title": "Arithmetic, Comparison, and Boolean Operators", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`==` versus `is`\n#\nimport random # The random module that can be used to generate pseudo-random numbers is part of the standard Python installation\n # but the name has still to be importent\na = random.randint(3, 9) # This generates an integer between 3 and 9 (both included), it is given the name 'a'\nb = random.randint(3, 9) # # This generates an integer between 3 and 9 (both included), it is given the name 'b'\nprint (a, b)\nprint(a==(a/b)*b + a%b) # == compares what is left of it to what is right of it and evaluates to True if both sides evaluate to the same value\n`==` compares value equality; `is` compares whether two names refer to the same object.\n8 4\nTrue", + "week": 1 + }, + { + "item_id": "ks-03c874b8bb", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Arithmetic operators\na+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b)*b + a%b == a always.\nFloor division and modulo\nprint(5 // 3, 5 % 3) # 1 2\nprint(-5 // 3, -5 % 3) # -2 1\nprint(5 // 2, 5 % 2) # 2 1\nprint(-5 // 2, -5 % 2) # -3 1", + "week": 1 + }, + { + "item_id": "ks-c0135e2a4a", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Comparison operators\n==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal; shorter sequence is 'less than' longer if all elements match up to shorter length.\nFloat precision issue\nprint(1.1 + 2.2 == 3.3) # False\nList/tuple comparison\nprint([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less)\nprint([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0)", + "week": 1 + }, + { + "item_id": "ks-c815ffe1d5", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Boolean operators\nx and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then 'or'. Use parentheses to avoid confusion.\nPrecedence trap\na=1; b=3\nprint(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter)\nprint((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT)", + "week": 1 + }, + { + "item_id": "cs-7eb8617d28", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "arithmetic_operators\nprint(5//2, 5%2)\n2 1", + "week": 1 + }, + { + "item_id": "cs-3cb4b8e8f9", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "arithmetic_operators\nprint(4 + 3)\nprint(4 - 3)\nprint(4 * 3)\nprint(4 / 3)\nprint(4 / 2)\nprint(4 ** 3)\n7\n1\n12\n1.3333333333333333\n2.0\n64", + "week": 1 + }, + { + "item_id": "cs-266616a010", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "arithmetic_operators\nprint(5 // 3, 5 % 3)\nprint(-5 // 3, -5 % 3)\nprint(5 // 2, 5 % 2)\nprint(-5 // 2, -5 % 2)\n1 2\n-2 1\n2 1\n-3 1", + "week": 1 + }, + { + "item_id": "cs-4f8a5f420b", + "card_id": "w1-operators-and-truth", + "topic": "Operators and Truth", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "arithmetic_operators\n#\nimport random # The random module that can be used to generate pseudo-random numbers is part of the standard Python installation\n # but the name has still to be importent\na = random.randint(3, 9) # This generates an integer between 3 and 9 (both included), it is given the name 'a'\nb = random.randint(3, 9) # # This generates an integer between 3 and 9 (both included), it is given the name 'b'\nprint (a, b)\nprint(a==(a/b)*b + a%b) # == compares what is left of it to what is right of it and evaluates to True if both sides evaluate to the same value\n8 4\nTrue", + "week": 1 + }, + { + "item_id": "aiq-1", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Slicing / mutability\nTrack which names point to the same object and which slice creates a copy before the mutation happens.\nSlicing / mutability", + "week": 1 + }, + { + "item_id": "aiq-2", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Slicing negative step\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.\nSlicing negative step", + "week": 1 + }, + { + "item_id": "aiq-3", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Correct. c: [::-1] reverses to [10,9,8,7,6,5,4,3,2,1], then [::2] takes every 2nd: [10,8,6,4,2]. Correct. d: [::2] gives [1,3,5,7,9], then [::-1] reverses: [9,7,5,3,1]. This does NOT give [10,8,6,4,2].\nExam • extra_practice • Q6", + "week": 1 + }, + { + "item_id": "aiq-5", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()", + "week": 1 + }, + { + "item_id": "aiq-6", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "range() and slicing both exclusive at stop\nrange(1,10,3)→[1,4,7] not including 10; l[2:7] goes up to but not including index 7", + "week": 1 + }, + { + "item_id": "kp-1", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Negative indices count from the end: `seq[-1]` is last and `seq[-len(seq)]` is first.", + "week": 1 + }, + { + "item_id": "kp-1-d1", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nPattern | Meaning | Example\nseq[i] | single element | x[-1]\nseq[a:b] | start inclusive, stop exclusive | x[1:4]\nseq[::-1] | reverse copy | x[::-1]\nseq[::2] | step through every other item | x[::2]", + "week": 1 + }, + { + "item_id": "kp-2", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`range(start, stop, step)` excludes `stop`; defaults are `start=0` and `step=1`, just like slicing excludes the stop index.", + "week": 1 + }, + { + "item_id": "kp-2-d1", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "range examples\nprint(list(range(6))) # [0, 1, 2, 3, 4, 5]\nprint(list(range(3,6))) # [3, 4, 5]\nprint(list(range(3,6,2))) # [3, 5]", + "week": 1 + }, + { + "item_id": "kp-3", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Pattern to remember: subset = numbers[::2][::-1]", + "week": 1 + }, + { + "item_id": "ai-example-1", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "range() output patterns\nprint(list(range(6))) # [0, 1, 2, 3, 4, 5]\nprint(list(range(3,6))) # [3, 4, 5]\nprint(list(range(3,6,2))) # [3, 5]\n`range(start, stop, step)` excludes `stop`; defaults are `start=0` and `step=1`, just like slicing excludes the stop index.", + "week": 1 + }, + { + "item_id": "ai-example-2", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "print(\"This is a string\")\nprint(\"This is a string\")\nprint('This is another string')", + "week": 1 + }, + { + "item_id": "ai-example-4", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "String quotes and escaping\nprint(\"This gives no ' error\")\nprint('This gives no \" error')", + "week": 1 + }, + { + "item_id": "ai-example-5", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "a = 'This is a string'\na = 'This is a string' \nb = \"This is another string\"\nprint(a)\nprint(b)\nprint(a,b)", + "week": 1 + }, + { + "item_id": "ai-example-6", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "a = 'This is a string'; b = 6; c = 0.0\n#\na = 'This is a string'; b = 6; c = 0.0 \nprint(f\"We know {a =}, {b= }, and {c = }\")", + "week": 1 + }, + { + "item_id": "ai-example-7", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "w1-sequences-and-access-core", + "subtopic_title": "Indexing, Slicing, and range()", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "slicing\nl1 = ['a', 'b']\nl2 = l1\nl2[-1] = 'c'\nprint(l1 == l3)\nl3 = l1[::]\nl3[-1] = 'c'\nprint(l1 == l3)", + "week": 1 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nA\nB\nC\nD\nA\nOption A uses range(0, 7, 3) which generates 0, 3, 6. The slices x[0:3], x[3:6], and x[6:9] correctly partition the list.", + "week": 1 + }, + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Correct. c: [::-1] reverses to [10,9,8,7,6,5,4,3,2,1], then [::2] takes every 2nd: [10,8,6,4,2]. Correct. d: [::2] gives [1,3,5,7,9], then [::-1] reverses: [9,7,5,3,1]. This does NOT give [10,8,6,4,2]. Correct answer (the one that does NOT work): d.", + "week": 1 + }, + { + "item_id": "ks-685cd3d828", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Indexing\nForward: 0, 1, 2, ... len-1. Backward: -1 (last), -2 (second to last), ..., -len (first). l1[0] == l1[-len(l1)]", + "week": 1 + }, + { + "item_id": "ks-be78ccac04", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "range()\nrange(start, stop, step). start default=0, step default=1. Stop is NOT inclusive. Works like slicing but defaults differ slightly.\nrange examples\nprint(list(range(6))) # [0, 1, 2, 3, 4, 5]\nprint(list(range(3,6))) # [3, 4, 5]\nprint(list(range(3,6,2))) # [3, 5]", + "week": 1 + }, + { + "item_id": "cs-curated-hw-seq-nth-occurrence", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Find the nth occurrence by advancing .index()\nx = ['A', 'B', 'A', 'C', 'B', 'A', 'B']\nn = 2\ni = -1\nfor _ in range(n):\n i = x.index('B', i + 1)\nprint(i)\n4", + "week": 1 + }, + { + "item_id": "cs-curated-hw-seq-slice-between-sentinels", + "card_id": "w1-sequences-and-access", + "topic": "Sequences and Access", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Slice between two sentinel values without hard-coding indices\nx = [21, 15, 29, 20, 15, 21, 38, 26]\nleft = x.index(15) + 1\nright = left + x[left:].index(15)\nprint(x[left:right])\n[29, 20]", + "week": 1 + }, + { + "item_id": "manual-import-names", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do different import forms change the names you can use locally?\n`import math` gives `math.sqrt`, `import math as m` gives `m.sqrt`, and `from math import sqrt` gives `sqrt(...)` directly.\nimport math\nimport math as m\nfrom math import sqrt", + "week": 1 + }, + { + "item_id": "manual-print-vs-return", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What is the difference between printing a value and returning a value from a function?\n`print(x)` shows a value on screen. `return x` sends a value back to the caller so it can be stored, reused, or printed later.\ndef f(x):\n return x + 1\n\nprint(f(3))", + "week": 1 + }, + { + "item_id": "manual-implicit-none", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What does a function return if it reaches the end without `return`?\nPython returns `None` if no `return` statement is executed.\ndef f():\n print('hi')\n\nprint(f())", + "week": 1 + }, + { + "item_id": "kp-1", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly.", + "week": 1 + }, + { + "item_id": "kp-1-d1", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Import styles\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import randint as rnd\nrnd(1, 10) # works\nrandint(1, 10) # ERROR", + "week": 1 + }, + { + "item_id": "kp-1-d2", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nCall | Use | Typical result\nint('123') | string to integer | 123\nfloat('123') | string to float | 123.0\nstr(123.0) | number to string | '123.0'\nround(x, 2) | round for display/checking | 2 decimals", + "week": 1 + }, + { + "item_id": "kp-2", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller.", + "week": 1 + }, + { + "item_id": "ai-example-1", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import randint as rnd\nrnd(1, 10) # works\nrandint(1, 10) # ERROR\n`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly.", + "week": 1 + }, + { + "item_id": "ai-example-2", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Direct import plus alias binds both names\nclear_names()\n\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n2025\nname 'extension' is not defined", + "week": 1 + }, + { + "item_id": "ai-example-3", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "from-import binds only the imported name\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n2025\n2025", + "week": 1 + }, + { + "item_id": "ai-example-4", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n2026\nname 'YEAR' is not defined", + "week": 1 + }, + { + "item_id": "ai-example-5", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "import module does not create bare globals\nclear_names()\n\nfrom extension import create_absolute_year as cay\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(cay(1))\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\nname 'create_absolute_year' is not defined\n2026", + "week": 1 + }, + { + "item_id": "ai-example-6", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Import module under its original name\nclear_names()\ntry:\n print(YEAR)\nexcept Exception as e:\n print(Exception)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n\nimport extension\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n\nname 'extension' is not defined\nname 'YEAR' is not defined\n2025", + "week": 1 + }, + { + "item_id": "ai-example-8", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "w1-functions-and-imports-core", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95,000\n4 32% $95,000\nIf your gross income is $50,000, you will pay 10% tax on the first $11,000, 12% tax on the next $34,000 and 22% tax on the last $5,000.\nWhich of the following function will return the output containing your net_income and your total_tax given your gross_income?\nFor example:\nIf we call the function as:\nincome_tax_calculator(50000)\nit should return:\n{'total_tax': 6280.0, 'net_income': 43720.0}\nA def income_tax_calculator(gross_income):\nresults = {}\nrate_1 = 0.10\nrate_2 = 0.12\nrate_3 = 0.22\nrate_4 = 0.32\nbracket_1 = 11000\nbracket_2 = 45000 - 11000\nbracket_3 = 95000 - 45000\nif gross_income > 95000:\ntotal_tax = ((gross_income - 95000) * rate_4) + (bracket_3 * rate_3) + (bracket_2 * rate_2)\n+ (bracket_1 * rate_1)\nelif 95000 >= gross_income > 45000:\ntotal_tax = ((gross_income - 45000) * rate_3) + (bracket_2 * rate_2) + (bracket_1 * rate_1)\nelif 45000 >= gross_income > 11000:\ntotal_tax = ((gross_income - 11000) * rate_2) + (bracket_1 * rate_1)\nelse:\ntotal_tax = gross_income * rate_1\nnet_income = gross_income - total_tax\nresults['total_tax'] = round(total_tax, 2)\nresults['net_income'] = round(net_income, 2)\nreturn results\nB def income_tax_calculator(gross_income):\n​ results = {}\nrate_1 = 0.10\nrate_2 = 0.12\nrate_3 = 0.22\nrate_4 = 0.32\nbracket_1 = 11000\nbracket_2 = 45000 - 11001\nbracket_3 = 95000 - 45001\ntotal_tax = (gross_income - 95001) * rate_4 + (bracket_3 * rate_3) + (bracket_2 * rate_2) +\n(bracket_1 * rate_1)\nnet_income = lambda gross_income, total_tax: gross_income - total_tax\nresults['total_tax'] = round(total_tax, 2)\nresults['net_income'] = round(net_income, 2)\nreturn results\nC def income_tax_calculator(gross_income):\n​ results = {}\nrate_1 = 0.10\nrate_2 = 0.12\nrate_3 = 0.22\nrate_4 = 0.32\nif gross_income <= 11000:\ntotal_tax = gross_income * rate_1\nif 45000 > gross_income > 11000:\ntotal_tax += (45000 - gross_income) * rate_2\nif 95000 > gross_income > 45000:\ntotal_tax += (95000 - gross_income) * rate_3\nelse:\ntotal_tax += (gross_income - 95000) * rate_4\nnet_income = gross_income - total_tax\nresults['total_tax'] = total_tax\nresults['net_income'] = net_income\nreturn(total_tax, net_income)\nD All of three functions will work as intended.\nCheck branch boundaries, rounding, and whether the function returns `{'total_tax': ..., 'net_income': ...}`.", + "week": 1 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which script does NOT print the correct answer for the area of a circle?\nA\nB\nC\nD\nC\nIf math is imported as constants, it must be referred to as 'constants.pi'. 'math.pi' will no longer be available unless 'math' was also imported directly.", + "week": 1 + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B uses list slicing `x[::-2]` which steps backwards through `x` by 2, retrieving indices -1, -3, -5, -7, and -9, which correspond to 5, 4, 3, 2, 1. Thus, both A and B are correct.", + "week": 1 + }, + { + "item_id": "exam-midterm_2023-12-w1-functions-and-imports", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You want to write a program to calculate your income tax for 2023.", + "week": 1 + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, 9]\nB [2, 4, 6, 8, 10]\nC [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nD None", + "week": 1 + }, + { + "item_id": "exam-midterm_2024-16-w1-functions-and-imports", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather alert system.", + "week": 1 + }, + { + "item_id": "ks-f43422a4cf", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Importing packages\nMultiple import styles. 'import X' makes X available. 'import X as Y' renames. 'from X import Z' brings Z directly into namespace. 'from X import Z as W' renames. Once you use 'as', the original name is no longer accessible.\nImport styles\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import randint as rnd\nrnd(1, 10) # works\nrandint(1, 10) # ERROR", + "week": 1 + }, + { + "item_id": "ks-b6a39f66a2", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
  • A function is a grouping of code that can perform a certain task and can be re-used \n
  • Print is a built-in function, that is a function that is part of the standard implementation of Python. Built-in fuctions like any function, can be used by calling their name. Built-in functions are already copied to your computer and the names of some of them like print, don't need to be imported\n
  • User functions are functions defined by you or other people that are not part of the standard Python implementation. (You will learn how to write your own…", + "week": 1 + }, + { + "item_id": "cs-beb6591b24", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "imports\nclear_names()\n\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n2025\nname 'extension' is not defined", + "week": 1 + }, + { + "item_id": "cs-6d0d650063", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "imports\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n2025\n2025", + "week": 1 + }, + { + "item_id": "cs-4155022ebf", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "imports\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\n2026\nname 'YEAR' is not defined", + "week": 1 + }, + { + "item_id": "cs-23b2cfd4d6", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "imports\nclear_names()\n\nfrom extension import create_absolute_year as cay\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(cay(1))\nexcept Exception as e:\n print(e)\nname 'create_absolute_year' is not defined\n2026", + "week": 1 + }, + { + "item_id": "cs-5b89a10dcd", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "imports\nclear_names()\ntry:\n print(YEAR)\nexcept Exception as e:\n print(Exception)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n\nimport extension\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n\nname 'extension' is not defined\nname 'YEAR' is not defined\n2025", + "week": 1 + }, + { + "item_id": "cs-c25503e5db", + "card_id": "w1-functions-and-imports", + "topic": "Functions and Imports", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "imports\n%%writefile extension.py\n# In this cell we create a python file and write that to the hard disk (either of your computer or to the cloud depending where you run your code.\n# We will import this file to show how to import the names of objects \n# into your Python program\nYEAR = 2025\ndef create_absolute_year(x):\n return YEAR + x\nOverwriting extension.py", + "week": 1 + }, + { + "item_id": "aiq-1", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • trial_midterm • Q2", + "week": 2 + }, + { + "item_id": "aiq-2", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Which update makes `library['books'] = 6` and adds `library['years']`?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q8", + "week": 2 + }, + { + "item_id": "aiq-3", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1, 2, 3, 4]\nC [11, 22, 33, 44]\nD [(1, 10), (2, 20), (3, 30), (4, 40)]", + "week": 2 + }, + { + "item_id": "aiq-6", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "RuntimeError: dictionary changed size during iteration\nAdding or deleting dict entries while iterating over it causes RuntimeError", + "week": 2 + }, + { + "item_id": "kp-1", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Dicts map unique immutable keys to values. `key in d` checks keys, and equality ignores insertion order.", + "week": 2 + }, + { + "item_id": "kp-1-d1", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Creating and using dicts\ncapitals = {}\ncapitals = dict()\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nprint(capitals['Belgium']) # Brussels\ndel(capitals['Belgium']) # delete key\ncapitals['Netherlands'] = 'Amsterdam' # insert/update\ncapitals.update({'France': 'Paris'}) # insert/update multiple", + "week": 2 + }, + { + "item_id": "kp-1-d2", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dict membership checks KEYS, not values\nd = {1: 4, 2: 3}\nprint(1 in d) # True (1 is a key)\nprint(4 in d) # False (4 is a value, not a key)", + "week": 2 + }, + { + "item_id": "kp-1-d3", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nOperation | What it gives | Exam note\nd[key] | value lookup | Key must exist\nkey in d | membership on keys | not values\nd.items() | (key, value) pairs | good for loops\nd.update(...) | mutates dict | returns None", + "week": 2 + }, + { + "item_id": "kp-2", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `.keys()`, `.values()`, and `.items()` for dictionary views; looping over a dict directly gives keys.", + "week": 2 + }, + { + "item_id": "kp-2-d1", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Looping over dict\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nfor key in capitals.keys():\n print(key)\nfor val in capitals.values():\n print(val)\nfor key, value in capitals.items():\n print(key, value)\n# These two are equivalent:\nfor key in capitals:\nfor key in capitals.keys():", + "week": 2 + }, + { + "item_id": "ai-example-1", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Creating and using dicts\ncapitals = {}\ncapitals = dict()\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nprint(capitals['Belgium']) # Brussels\ndel(capitals['Belgium']) # delete key\ncapitals['Netherlands'] = 'Amsterdam' # insert/update\ncapitals.update({'France': 'Paris'}) # insert/update multiple\nDicts map unique immutable keys to values. `key in d` checks keys, and equality ignores insertion order.", + "week": 2 + }, + { + "item_id": "ai-example-2", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Dict membership checks KEYS, not values\nd = {1: 4, 2: 3}\nprint(1 in d) # True (1 is a key)\nprint(4 in d) # False (4 is a value, not a key)\nDicts map unique immutable keys to values. `key in d` checks keys, and equality ignores insertion order.", + "week": 2 + }, + { + "item_id": "ai-example-4", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Dictionary creation and lookup\nsquares = {1:1, 2:4, 3:9, 4:16}\nprint(squares)\nl1 = [1, 2, 3, 4]\nl2 = [1, 4, 9, 16]\nsquares = dict(zip(l1, l2))\nprint(squares)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", + "week": 2 + }, + { + "item_id": "ai-example-5", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Dictionary creation and lookup\nsquares = {}\nprint(squares)\nsquares = dict()\nprint(squares)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", + "week": 2 + }, + { + "item_id": "ai-example-6", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Dictionary creation and lookup\nsquares = {1:1, 2:4, 3:9, 4:16}\ndel(squares[2])\nprint(squares)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", + "week": 2 + }, + { + "item_id": "ai-example-7", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Dictionary creation and lookup\na = 1\nb = {1:1}\nprint({a:b})\ntry:\n print({b:a})\nexcept Exception as e:\n print(e)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", + "week": 2 + }, + { + "item_id": "ai-example-8", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Dictionary creation and lookup\ncapitals = {'Estonia': 'Tallinn', 'Belgium': 'Brussels', 'France': 'Paris'}\nprint(capitals['Belgium'])\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", + "week": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?\nA\nB\nC\nD\nC\nBoth methods correctly calculate the cumulative sums based on key values, though Option B is more efficient.", + "week": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?\nA\nB\nC\nD\nA\nBoth d1 and d2 result in the same dictionary: {1: 2, 2: 3, 3: 4, 4: 5}.", + "week": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables.", + "week": 2 + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A correctly zips the numbers 1 to 5 with the corresponding Roman numerals to create the dictionary.", + "week": 2 + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A correctly iterates through both lists simultaneously using zip and assigns the correct keys and values.", + "week": 2 + }, + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A correctly identifies the maximum rating from the values and then prints the corresponding employees.", + "week": 2 + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a valid dictionary comprehension that iterates through `words`, setting each `word` as the key and `len(word)` as the value.", + "week": 2 + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the following code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97\na\nb\nc\nd\nc\nOption A iterates over 'aeiou' and correctly creates the dictionary. Option B iterates over 'aeiou' and also checks if the vowel is in 'aeiou', which is redundant but still valid and produces the correct dictionary. Thus, both work correctly.", + "week": 2 + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a new dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A uses zip to combine the lists and enumerate with start=1 to get match numbers starting from 1. It assigns a tuple of goals to each match number. Option B assigns the sum instead of a tuple. Options C and D don't use start=1 for enumerate, so keys will start from 0.", + "week": 2 + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?\na\nb\nc\nd\na\nDictionaries are not sliceable, so options B and D will raise TypeErrors. Option C creates a list of tuples, and the sum() function cannot add tuples together in this context (it will raise a TypeError when trying to add an int to a tuple). Option A extracts the first three keys, gets their corresponding values in a list comprehension, and calculates the average correctly.", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-2-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"],\n- change the value of the key \"books\" to 6.\nThe new value of the dictionary library should be:\n{\"books\" : 6,\n\"genres\" : ['action', 'romance', 'thriller', 'classics'],\n\"years\" : [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]}\nWhich of the programs below will work as intended?\nA library[\"books\"] = 6\nlibrary.update({\"years\": [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]})\nB library[\"books\"] = 6\nlibrary[\"years\"] = [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]\nC Both of the given options\nD None of the given options", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1, 2, 3, 4]\nC [11, 22, 33, 44]\nD [(1, 10), (2, 20), (3, 30), (4, 40)]", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_count = my_count_function(\"peach\")\nWhich of the code snippets of code below prints something different than the other code snippets?\nA print(len(apple_count.keys()))\nB print(len(peach_count.keys()))\nC print(sum(apple_count.values()))\nD print(sum(peach_count.values()))", + "week": 2 + }, + { + "item_id": "ks-65c4de2e9d", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Dictionaries\nSets of key:value pairs. Keys must be unique and immutable (hashable). Dictionaries are unordered for equality ({1:1,2:2}=={2:2,1:1} is True). Cannot be sorted. You can check membership with 'in' — this checks KEYS only. Keys() gives key sequence, values() gives value sequence, items() gives tuples.\nCreating and using dicts\ncapitals = {}\ncapitals = dict()\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nprint(capitals['Belgium']) # Brussels\ndel(capitals['Belgium']) # delete key\ncapitals['Netherlands'] = 'Amsterdam' # insert/update\ncapitals.update({'France': 'Paris'}) # insert/update multiple\nDict membership checks KEYS, not values\nd = {1: 4, 2: 3}\nprint(1 in d) # True (1 is a key)\nprint(4 in d) # False (4 is a value, not a key)\nCreating dict from two lists\nl1 = [1, 2, 3, 4]\nl2 = [1, 4, 9, 16]\nsquares = dict(zip(l1, l2))\nprint(squares) # {1:1, 2:4, 3:9, 4:16}\nDict equality ignores order\nprint({1:1, 2:2} == {2:2, 1:1}) # True\nprint([1,2] == [2,1]) # False", + "week": 2 + }, + { + "item_id": "ks-adb6d9f967", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Looping over dictionaries\n.keys() → key sequence. .values() → value sequence. .items() → sequence of (key, value) tuples. 'for key in dict' is the same as 'for key in dict.keys()'.\nLooping over dict\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nfor key in capitals.keys():\n print(key)\nfor val in capitals.values():\n print(val)\nfor key, value in capitals.items():\n print(key, value)\n# These two are equivalent:\nfor key in capitals:\nfor key in capitals.keys():", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-23-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-5-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "What is the output of the program below?", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-6-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following dictionary:\nsample_dict = {\n\"name\": \"Kim\",\n\"age\": 25,\n\"birthdate\": \"3-2-1998\",\n\"city\": \"Amsterdam\"}\nSuppose you want to create a dictionary that only contains the keys 'name' and 'city'.\nWhich of the following code snippets return(s) the desired dictionary?\nA keys = [\"name\", \"city\"]\nnew_dict = {}\nfor k in keys:\nnew_dict[k] = sample_dict[k]\nnew_dict\nB keys = [\"age\", \"birthdate\"]\nnew_dict = {}\nnew_keys = sample_dict.keys() - keys\nfor k in new_keys:\nnew_dict[k] = sample_dict[k]\nnew_dict\nC None of the given options\nD Both of the given options", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\" becomes 7\nSo the final dictionary should look like:\n{'shirts': 7, 'colors': ['red', 'yellow', 'blue', 'pink'], 'shoes': ['sneakers', 'heels']}\nWhich of the programs below will work as intended?\nA shoes = {'shoes': ['sneakers', 'heels']}\ncloset[\"shirts\"] = 7\ncloset = dict(zip(closet, shoes))\nB closet.keys() = closet.keys() + \"shoes\"\ncloset.values() = [7, ['red', 'yellow', 'blue', 'pink'], ['sneakers', 'heels']]\nC Both of the given options\nD None of the given options", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\ncounts[letter] = string.count(letter)\nreturn counts\nAnd you create the following two dictionaries:\ndesk_count = my_count_function(\"desk\")\nlaptop_count = my_count_function(\"laptop\")\nWhich of the lines of code below returns something different than the rest?\nA len(desk_count)\nB max(laptop_count.values())*2\nC sum(desk_count.values())\nD sum(laptop_count.keys())", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92.0, 98.0, 100.0],\n\"quizzes\": [82.0, 83.0, 91.0],\n\"tests\": [89.0, 97.0]},\n\"david\": {\"name\": \"David\",\n\"homework\": [0.0, 87.0, 75.0, 22.0],\n\"quizzes\": [0.0, 75.0, 78.0],\n\"tests\": [100.0, 100.0]}\n}\nYou want to create a function that calculates the average final course grade of a student.\nThe final course grade is calculated as 20% average homework grade, 10% average quizzes grade and 70% average tests grade.\nWhich of the following programs will work as intended and will give the final course grade of Eva?\nA def average(numbers):\nreturn sum(numbers)/(len(numbers))\ndef final_average(student):\nhomework = average(student['homework'])\nquizzes = average(student['quizzes'])\ntests = average(student['tests'])\nreturn round(0.2*homework + 0.1*quizzes + 0.7*tests, 2)\nfinal_average(students[\"eva\"])\nB def final_average(student):\ndef average(numbers):\nreturn sum(numbers)/(len(numbers)\nhomework = average(student['home…", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-8-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "You need to write a function called dict_keys that checks whether a certain key is in available in a certain dictionary.", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-10-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"],\n- change the value of the key \"books\" to 6.\nThe new value of the dictionary library should be:\n{\"books\" : 6,\n\"genres\" : ['action', 'romance', 'thriller', 'classics'],\n\"years\" : [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]}\nWhich of the programs below will work as intended?\nA library[\"books\"] = 6\nlibrary.update({\"years\": [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]})\nB library[\"books\"] = 6\nlibrary[\"years\"] = [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]\nC Both of the given options\nD None of the given options", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-11-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_count = my_count_function(\"peach\")\nWhich of the code snippets of code below prints something different than the other code snippets?\nA print(sum(apple_count.values()))\nB print(len(apple_count.keys()))\nC print(sum(peach_count.values()))\nD print(len(peach_count.keys()))", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-12-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA [10, 20, 30, 40, 1, 2, 3, 4]\nB [11, 22, 33, 44]\nC This code will result in an error because you cannot concatenate two lists using the + operator.\nD [(1, 10), (2, 20), (3, 30), (4, 40)]", + "week": 2 + }, + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and lowest scores and the values are a list of names of the players that attained the corresponding scores.\n\nWhich of the following code snippets implements this?\na\nb\nc\nd\nc\nBoth snippets correctly find the global max (6) and min (1), then iterate to find which players achieved those scores. Both produce the same correct output. Note: both Adelbrecht and Hortensia achieved score 6, so winners = ['Adelbrecht', 'Hortensia'].", + "week": 2 + }, + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the for loop is indented under the average_score line as if it's a block, but there's no colon). This causes an IndentationError. Option b works correctly. Actually option a depends on whether the indentation shown is a tab after a plain statement — in Python that's an IndentationError. So only b works. Correct: b.", + "week": 2 + }, + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a correctly counts grades: initialises to 0 and increments. Produces {9:3, 10:2, 11:1}. Option b creates lists of student names, not counts — produces {9:['A','C','F'], 10:['B','E'], 11:['D']}, not the required format. Correct: a.", + "week": 2 + }, + { + "item_id": "exam-extra_practice-8-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "x = {'a': [1, 2], 'b':[3, 4], 'c':[5, 6], 'd':[7, 8]}\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\na: x['a'][1]=2, x['b'][0]=3, 2*3=6, x['c'][1]=6. True. b: x['b'][0]=3, x['c'][0]=5, 3+5=8, x['d'][1]=8. True. c: x['d'][0]=7, x['c'][0]=5, 7-5=2, x['a'][1]=2. True. All are True, so d is correct.", + "week": 2 + }, + { + "item_id": "exam-extra_practice-12-w2-dictionaries-and-mappings", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "def counter(y):\n\tx = {}\n\tfor index, element in enumerate(y):\n\t\tif index != int(element) and int(element) % 2 == 0:\n\t\t\tx[element] = len(element)\n\treturn x\n\nWhat will this function return when called as:\ncounter(['12345678', '1', '123', '1234', '12345', '12', '6', '1', '123456'])\na\nb\nc\nd\na\nindex 0: '12345678', int=12345678, index(0)!=12345678 ✓, even ✓ → add, len=8. index 1: '1', int=1, index==int → skip. index 2: '123', int=123, odd → skip. index 3: '1234', int=1234, index(3)!=1234 ✓, even ✓ → add, len=4. index 4: '12345', int=12345, odd → skip. index 5: '12', int=12, index(5)!=12 ✓, even ✓ → add, len=2. index 6: '6', int=6, index(6)==6 → skip. index 7: '1', int=1, odd → skip. index 8: '123456', int=123456, index(8)!=123456 ✓, even ✓ → add, len=6. Result: {'12345678':8,'1234':4,'12':2,'123456':6}. Correct: a.", + "week": 2 + }, + { + "item_id": "cs-curated-hw-dict-digit-frequency", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Count only digit characters that actually appear\nx = ['1', 'a', 'X', '2', 'b', 'Y', '1', 'a', 'X', '1', 'a', 'X']\ncounts = {}\nfor digit in '0123456789':\n if digit in x:\n counts[digit] = x.count(digit)\nprint(counts)\n{'1': 3, '2': 1}", + "week": 2 + }, + { + "item_id": "cs-curated-hw-dict-delete-shared-keys", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Delete keys only when they also appear in a reference dict\nx = {'a': 1, 'b': 2, 'c': 3}\nto_remove = {'c': 3, 'd': 3}\nfor key in to_remove:\n if key in x:\n del x[key]\nprint(x)\n{'a': 1, 'b': 2}", + "week": 2 + }, + { + "item_id": "cs-curated-hw-dict-project-values-sorted-keys", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Sort keys first, then project values in that order\nx = {1: 3, 3: 4, 2: 5}\nsorted_keys = sorted(x.keys(), reverse=True)\nresult = [x[key] for key in sorted_keys]\nprint(result)\n[4, 5, 3]", + "week": 2 + }, + { + "item_id": "aiq-1", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Assume you already have a variable a, which is an integer between 1 and 4.\nExam • midterm_2023 • Q15\nmylist = [1, 3, 5, 7, 9]\nprint(mylist[a] + mylist[-a])", + "week": 2 + }, + { + "item_id": "aiq-2", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.", + "week": 2 + }, + { + "item_id": "aiq-3", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?", + "week": 2 + }, + { + "item_id": "aiq-4", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False", + "week": 2 + }, + { + "item_id": "kp-1", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Lists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections.", + "week": 2 + }, + { + "item_id": "kp-1-d1", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Ordering comparison\nprint([1,2] == [2,1]) # False (ordered)\nprint((1,2) == (2,1)) # False (ordered)\nprint('12' == '21') # False (ordered)\nprint({1,2} == {2,1}) # True (unordered)\nprint({1:1,2:2}=={2:2,1:1}) # True (unordered)", + "week": 2 + }, + { + "item_id": "kp-2", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Unordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update().", + "week": 2 + }, + { + "item_id": "kp-2-d1", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Set operations\ncountries = set() # empty set (NOT {})\ncountries = {'Andorra', 'Belgium'}\nprint({1,2,2} == {2,1}) # True (duplicates ignored)\nprint(len({1,2,2})) # 2\ncountries.remove('Andorra')\ncountries.add('Greece')\ncountries.update({'Spain', 'Italy'})", + "week": 2 + }, + { + "item_id": "ai-example-1", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Ordering comparison\nprint([1,2] == [2,1]) # False (ordered)\nprint((1,2) == (2,1)) # False (ordered)\nprint('12' == '21') # False (ordered)\nprint({1,2} == {2,1}) # True (unordered)\nprint({1:1,2:2}=={2:2,1:1}) # True (unordered)\nLists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections.", + "week": 2 + }, + { + "item_id": "ai-example-2", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Set operations\ncountries = set() # empty set (NOT {})\ncountries = {'Andorra', 'Belgium'}\nprint({1,2,2} == {2,1}) # True (duplicates ignored)\nprint(len({1,2,2})) # 2\ncountries.remove('Andorra')\ncountries.add('Greece')\ncountries.update({'Spain', 'Italy'})\nUnordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update().", + "week": 2 + }, + { + "item_id": "ai-example-3", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Create a list literal\nsquares = [1, 4, 9, 16]\nprint(squares)", + "week": 2 + }, + { + "item_id": "ai-example-4", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Delete by index with `del`\nsquares = [1, 4, 5, 9, 16]\ndel(squares[2])\nprint(squares)", + "week": 2 + }, + { + "item_id": "ai-example-5", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Two ways to create an empty list\nsquares = []\nprint(squares)\nsquares = list()\nprint(squares)", + "week": 2 + }, + { + "item_id": "ai-example-6", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Lists are mutable: replace by index\nsquares = [1, 4, 8, 15]\nsquares[2] = 9\nsquares[3] = 16\nprint(squares)", + "week": 2 + }, + { + "item_id": "ai-example-7", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "List method effects and resulting list\nsquares = [1, 4, 9, 16]\nsquares.append(16)\nsquares.append(25)\nprint(squares)\nCheck whether the method mutates the list in place and what the list looks like after each call.", + "week": 2 + }, + { + "item_id": "ai-example-8", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "w2-lists-and-sets-core", + "subtopic_title": "Sequences, Uniqueness, and Common Operations", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "List method effects and resulting list\nif 16 not in squares:\n squares.append(16)\nif 25 not in squares:\n squares.append(25) \nprint(squares)\nCheck whether the method mutates the list in place and what the list looks like after each call.", + "week": 2 + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True.", + "week": 2 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True.", + "week": 2 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by 2 elements at a time, picking the second instance of each number in reverse order, which also yields [5, 4, 3, 2, 1]. Both work.", + "week": 2 + }, + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions.", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-15-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assume you already have a variable a, which is an integer between 1 and 4.\nWhat is the ​output of the following ​code snippet?", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC 0\nD None of the given options.", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-22-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?\nA z = [[\"a\", \"b\", \"c\"], [1, 2, 3, 4]]\nprint(z[0][1] + str(z[1][3])*3)\nB print('b'+ str(8 % 4)*3)\nC print('b' + str(len(x)*3))\nD y = [1, 2, 3, 4]\nprint('b'+ max(y)*3)", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-23-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\nmylist = [1, 2, 5, 7, 9, 12]\nnew_list1 = mylist[0:3]\nnew_list2 = mylist[1:4]\nprint(new_list1 + new_list2)\nWhat will be printed?\nA [1, 2, 5, 2, 5, 7]\nB [1, 2, 5, 7, 2, 5, 7, 9]\nC [2, 5, 7, 5, 7, 9]\nD [2, 5, 5, 7]", + "week": 2 + }, + { + "item_id": "ks-4258f15a6c", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Lists vs Dictionaries vs Sets — ordered/unordered\nLists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections.\nOrdering comparison\nprint([1,2] == [2,1]) # False (ordered)\nprint((1,2) == (2,1)) # False (ordered)\nprint('12' == '21') # False (ordered)\nprint({1,2} == {2,1}) # True (unordered)\nprint({1:1,2:2}=={2:2,1:1}) # True (unordered)", + "week": 2 + }, + { + "item_id": "ks-08ac820c2f", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Sets\nUnordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update().\nSet operations\ncountries = set() # empty set (NOT {})\ncountries = {'Andorra', 'Belgium'}\nprint({1,2,2} == {2,1}) # True (duplicates ignored)\nprint(len({1,2,2})) # 2\ncountries.remove('Andorra')\ncountries.add('Greece')\ncountries.update({'Spain', 'Italy'})", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-24-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "You have the following list:\nmy_list = [1,2,3,4]\nWhich one of the following lines of code lines does not print 4 as the output?\nA print(max(my_list))\nB print(len(my_list))\nC print(my_list[4])\nD print(my_list[-1])", + "week": 2 + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "card_id": "w2-lists-and-sets", + "topic": "Lists and Sets", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\nb\nc\nd\nd\nOption a: for (1,2,2), tuple has no .count() — wait, actually tuples DO have .count(). For [1,2,2]: element 2 has count>1 so counter=2, returns False. Original returns False. But for a tuple (1,2,2): tuple has .count(), works. But option b: l1[l1.index(element)+1:] — tuples support slicing and indexing too. Let's re-examine: for a tuple (1,2,2), both a and b should work the same. Actually option a counts ALL duplicated elements (counts 2 twice for [1,2,2]), making counter=2, so counter==0 is False. Original is False too. Both match. For option b applied to tuple: l1[l1.index(element)+1:] works for tuples too. Actually both a and b return same values as original. Correct: d.", + "week": 2 + }, + { + "item_id": "manual-bool-precedence", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do `not`, `and`, and `or` combine when there are no extra parentheses?\n`not` is evaluated first, then `and`, then `or`, so parenthesize whenever the intended logic is not obvious.\nprint(not False and True or False)", + "week": 2 + }, + { + "item_id": "manual-filter-condition", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Trace `main(lst, condition)` and identify which values satisfy `lambda x: x % 2 != 0`.\nApply the condition to one element first, then keep only the values for which it returns `True`.\ndef main(lst, condition):\n return [x for x in lst if condition(x)]", + "week": 2 + }, + { + "item_id": "manual-conditional-expression", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "When should you use `x if cond else y` instead of a multi-line `if/else` block?\nUse the conditional expression for a single value choice; use a full block when each branch needs multiple statements.\nlabel = 'pass' if score >= 10 else 'fail'", + "week": 2 + }, + { + "item_id": "kp-manual-precedence", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`not` binds tighter than `and`, and `and` binds tighter than `or`; add parentheses when the intended grouping is not obvious.", + "week": 2 + }, + { + "item_id": "kp-manual-ternary", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `x if cond else y` when both branches are single expressions; use a full `if/elif/else` block when the branches need multiple statements.", + "week": 2 + }, + { + "item_id": "ai-example-1", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "w2-conditions-core", + "subtopic_title": "Comparisons, `in`, Precedence, and Conditional Expressions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Precedence trap\na=1; b=3\n# WRONG: Python evaluates 'and' before 'or'\nprint(a==1 or a==2 and b==1 or b==2) # True (unexpected)\n# CORRECT: use brackets\nprint((a==1 or a==2) and (b==1 or b==2)) # False\nPrecedence (high to low): comparisons → not → and → or. Use parentheses to be explicit. 'in' checks membership in sequence/set/dict-keys.\nTrue\nFalse", + "week": 2 + }, + { + "item_id": "ai-example-2", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "w2-conditions-core", + "subtopic_title": "Comparisons, `in`, Precedence, and Conditional Expressions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Inclusion check — 'in' operator\nprint(1 in [1,2,3]) # True\nprint(1 in (1,2,3)) # True\nprint('1' in '123') # True (substring)\nprint(1 in {1:4, 2:3}) # True (checks keys)\nprint(4 in {1:4, 2:3}) # False (4 is value, not key)\nprint(1 in {1,2,3}) # True\nPrecedence (high to low): comparisons → not → and → or. Use parentheses to be explicit. 'in' checks membership in sequence/set/dict-keys.\nTrue\nTrue\nTrue\nTrue\nFalse\nTrue", + "week": 2 + }, + { + "item_id": "ai-example-3", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "w2-conditions-core", + "subtopic_title": "Comparisons, `in`, Precedence, and Conditional Expressions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "if/elif/else structure\nif condition_1:\n expression_1\nelif condition_2:\n expression_2\n expression_3\nelse:\n expression_4\nif/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critical — all code in a block must have same indentation. Conditional expression (ternary): value_if_true if condition else value_if_false.", + "week": 2 + }, + { + "item_id": "ai-example-4", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "w2-conditions-core", + "subtopic_title": "Comparisons, `in`, Precedence, and Conditional Expressions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Conditional expression (ternary)\n# Statement form:\nif a > 0:\n b = a\nelse:\n b = 0\n# Expression form:\nb = a if a > 0 else 0\n# Even simpler:\nb = max(0, a)\nif/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critical — all code in a block must have same indentation. Conditional expression (ternary): value_if_true if condition else value_if_false.", + "week": 2 + }, + { + "item_id": "ai-example-5", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "w2-conditions-core", + "subtopic_title": "Comparisons, `in`, Precedence, and Conditional Expressions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Comparison operators return booleans\nprint(3 > 2)\nA comparison like `3 > 2` evaluates to either `True` or `False`.\nTrue", + "week": 2 + }, + { + "item_id": "ai-example-8", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "w2-conditions-core", + "subtopic_title": "Comparisons, `in`, Precedence, and Conditional Expressions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`not` flips booleans\nprint(not True) \nprint(not False)\n`not True` becomes `False` and `not False` becomes `True`.\nFalse\nTrue", + "week": 2 + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?\na\nb\nc\nd\na\nOption A correctly removes spaces, converts to lowercase, lists characters, sorts them, and compares the results. Option B and C use .sort() which returns None, and D uses .replace() on a list.", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-1-w2-conditions", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What is the output of the following code snippet?", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nC [1, 3, 5, 7, 9]\nD None", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-13-w2-conditions", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather\nalert system.", + "week": 2 + }, + { + "item_id": "ks-4b427a2425", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Conditions and boolean operators — precedence\nPrecedence (high to low): comparisons → not → and → or. Use parentheses to be explicit. 'in' checks membership in sequence/set/dict-keys.\nPrecedence trap\na=1; b=3\n# WRONG: Python evaluates 'and' before 'or'\nprint(a==1 or a==2 and b==1 or b==2) # True (unexpected)\n# CORRECT: use brackets\nprint((a==1 or a==2) and (b==1 or b==2)) # False\nInclusion check — 'in' operator\nprint(1 in [1,2,3]) # True\nprint(1 in (1,2,3)) # True\nprint('1' in '123') # True (substring)\nprint(1 in {1:4, 2:3}) # True (checks keys)\nprint(4 in {1:4, 2:3}) # False (4 is value, not key)\nprint(1 in {1,2,3}) # True", + "week": 2 + }, + { + "item_id": "ks-c19999c074", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Conditional statements and expressions\nif/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critical — all code in a block must have same indentation. Conditional expression (ternary): value_if_true if condition else value_if_false.\nif/elif/else structure\nif condition_1:\n expression_1\nelif condition_2:\n expression_2\n expression_3\nelse:\n expression_4\nConditional expression (ternary)\n# Statement form:\nif a > 0:\n b = a\nelse:\n b = 0\n# Expression form:\nb = a if a > 0 else 0\n# Even simpler:\nb = max(0, a)", + "week": 2 + }, + { + "item_id": "cs-curated-hw-conditions-first-match-wins", + "card_id": "w2-conditions", + "topic": "Conditions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Branch order matters because the first matching condition wins\nx = [5, 10, 15, 20]\na, b, c, d = 4, 9, 13, 15\nresult = []\nfor element in x:\n if element <= d:\n label = 'cat4'\n elif element >= c:\n label = 'cat3'\n elif element < b:\n label = 'cat2'\n elif element > a:\n label = 'cat1'\n else:\n label = 'catunknown'\n result.append(label)\nprint(result)\n['cat4', 'cat4', 'cat4', 'cat3']", + "week": 2 + }, + { + "item_id": "manual-loop-translate", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Translate `alphabet[1::2]` into a loop that collects every second character starting at index 1.\nInitialize an empty result, loop over the needed indices, and append the selected characters in order.\nresult = ''\nfor i in range(1, len(alphabet), 2):\n result += alphabet[i]", + "week": 2 + }, + { + "item_id": "manual-break-continue", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What is the difference between `break` and `continue` inside a loop?\n`break` exits the loop immediately; `continue` skips the rest of the current iteration and moves to the next one.\nfor x in data:\n if x < 0:\n continue\n if x == 0:\n break", + "week": 2 + }, + { + "item_id": "manual-enumerate-zip", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "When do you reach for `enumerate` versus `zip`?\nUse `enumerate(seq)` when you need index and value together; use `zip(a, b)` when you need items from multiple iterables in parallel.\nfor i, value in enumerate(seq):\n ...\nfor left, right in zip(a, b):\n ...", + "week": 2 + }, + { + "item_id": "kp-manual-loop-core", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `for` when you already have an iterable; use `while` when repetition should continue only while a condition stays `True`.", + "week": 2 + }, + { + "item_id": "kp-manual-break-continue", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`break` exits the loop immediately; `continue` skips the rest of the current iteration and moves to the next one.", + "week": 2 + }, + { + "item_id": "kp-manual-enumerate", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`enumerate(seq, start)` gives `(index, value)` pairs; `zip(a, b)` gives tuples of items from multiple iterables in parallel.", + "week": 2 + }, + { + "item_id": "kp-manual-while-truthy", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A `while` condition is checked before every iteration, so a list loop like `while items:` keeps going only while the list is non-empty.", + "week": 2 + }, + { + "item_id": "ai-example-2", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Skip certain values with `continue`\ntotal = 0\nfor number in [1, 2, '3', 3, 5, 7]:\n if type(number) == str:\n continue\n total += number\nprint(total) # 18\nUse `continue` to ignore the current item and jump straight to the next iteration.\n18", + "week": 2 + }, + { + "item_id": "ai-example-3", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Loop variable not used — use _\nfor _ in range(5):\n print('Hello') # prints Hello 5 times\nUse `_` when the loop should repeat a fixed number of times but the loop variable itself is not needed.\nHello\nHello\nHello\nHello\nHello", + "week": 2 + }, + { + "item_id": "ai-example-4", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`enumerate(seq, start=1)`\ncountries = ['Andorra', 'Belgium']\nfor index, country in enumerate(countries, 1):\n print(country, 'has index:', index)\n# Andorra has index: 1\n# Belgium has index: 2\nUse `enumerate` when you need both index and value, and set `start=1` if the numbering should begin at 1.\nAndorra has index: 1\nBelgium has index: 2", + "week": 2 + }, + { + "item_id": "ai-example-5", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`zip(a, b)` pairs items in parallel\ncountries = ['Andorra', 'Belgium']\ncapitals = ['Andorra la Vella', 'Brussels']\nfor country, capital in zip(countries, capitals):\n print(country, 'has capital:', capital)\nUse `zip` when two sequences should be processed position by position together.\nAndorra has capital: Andorra la Vella\nBelgium has capital: Brussels", + "week": 2 + }, + { + "item_id": "ai-example-7", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`while items:` repeats until the list is empty\nl1 = [1, 2, 3, 4, 5, 6]\ntotal = 0\nwhile l1: # truthy while list is non-empty\n total += l1[0]\n del l1[0]\nprint(total) # 21\nNon-empty lists are truthy and empty lists are falsy, so `while items:` is a common consume-until-empty loop.\n21", + "week": 2 + }, + { + "item_id": "manual-loop-max-sublist-sum", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Keep the sub-list whose elements have the largest sum\nlists = [[1, 2], [4, 4], [3, 3, 1]]\nbest = lists[0]\nfor current in lists[1:]:\n if sum(current) > sum(best):\n best = current\nprint(best)\nStore the current best sub-list, compare `sum(current)` with `sum(best)` on each iteration, and update the winner when you find a larger total.\n[4, 4]", + "week": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).\nA\nB\nC\nD\nB\nOption B correctly updates the 'previous' state at the end of each iteration to match the logic of the target output.", + "week": 2 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted strings to the list, resulting in 10 elements.", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-2-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What is the output of the following code snippet?", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-3-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 != 0:\nprint(i)\nD x = '12345'\nfor i in x:\nif i % 2 != 0:\nprint(i)", + "week": 2 + }, + { + "item_id": "exam-trial_midterm-5-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 != 0:\nprint(i)\nC x = '12345'\nfor i in x:\nif i % 2 != 0:\nprint(i)\nD for i in range(7, 1, -2):\nprint(i)", + "week": 2 + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the sorting order of the elements in a list.\nA values = []\nfor index, value in enumerate(alphabet, start=1):\nif index % 2 == 0:\nvalues.append(value)\nprint(values)\nB values = []\nfor index, value in enumerate(alphabet[::-1]):\nif index % 2 == 0:\nvalues.append(value)\nvalues.reverse()\nprint(values)\nC Both of the given options.\nD None of the given options.", + "week": 2 + }, + { + "item_id": "ks-72c9eada91", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Augmented assignment operators\nShorthand for a = a OP b. All arithmetic operators have an augmented form.\nAll augmented operators\na += 1 # a = a + 1\na -= 2 # a = a - 2\na *= 3 # a = a * 3\na /= 4 # a = a / 4\na //= 5 # a = a // 5\na %= 6 # a = a % 6", + "week": 2 + }, + { + "item_id": "ks-bddafc66a0", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "For-loops\nfor variable in sequence: expression. break: exit loop entirely. continue: skip to next iteration. You don't have to use the loop variable; use _ as convention when not needed.\nFor-loop with continue\ntotal = 0\nfor number in [1, 2, '3', 3, 5, 7]:\n if type(number) == str:\n continue\n total += number\nprint(total) # 18\nLoop variable not used — use _\nfor _ in range(5):\n print('Hello') # prints Hello 5 times", + "week": 2 + }, + { + "item_id": "ks-59aaf6b0ee", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "enumerate()\nProvides index alongside value when looping. enumerate(seq, start) — second arg sets the start index (default 0).\nenumerate with start=1\ncountries = ['Andorra', 'Belgium']\nfor index, country in enumerate(countries, 1):\n print(country, 'has index:', index)\n# Andorra has index: 1\n# Belgium has index: 2", + "week": 2 + }, + { + "item_id": "ks-4c6274845e", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "zip()\nLoops over multiple sequences in parallel. Zips sequences of equal length (Python handles unequal lengths but it can be messy). Can zip sequences of different types. Can zip more than 2.\nzip two lists\ncountries = ['Andorra', 'Belgium']\ncapitals = ['Andorra la Vella', 'Brussels']\nfor country, capital in zip(countries, capitals):\n print(country, 'has capital:', capital)", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-9-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-17-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following function which take a list of numerical strings as an argument.", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor char in key:\nif char == character:\ncount += 1\ny[key] = count\nreturn y\nWhat would be returned by this function, if we call the function twice as follows:\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'], 'i')\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'])\nA {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 1, 'Julia': 1, 'Ian': 1, 'Noah': 1, 'Liam': 1, 'Anna': 1}\nB {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 0, 'Julia': 0, 'Ian': 0, 'Noah': 0, 'Liam': 0, 'Anna': 0}\nC The first function call will result in an error because there are too many arguments.\nD The second function call will result in an error because there is a missing argument.", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-20-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "What is the output of the program below?", + "week": 2 + }, + { + "item_id": "exam-midterm_2024-21-w2-loops", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?", + "week": 2 + }, + { + "item_id": "ks-8ad541fef7", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "While-loops\nwhile condition: expression. Checks condition BEFORE each execution. Use break and continue. Watch for infinite loops (Ctrl+C to exit). Use when you don't know beforehand how many iterations are needed. For-loops can always be replaced by while-loops.\nWhile with break/continue\ntotal = 0\nwhile True:\n number = int(input('give a number, or 100 to stop '))\n if number == 100:\n break\n if number % 2 == 0:\n continue\n total += number\nprint(total)\nTruthy/Falsy in while condition\nl1 = [1, 2, 3, 4, 5, 6]\ntotal = 0\nwhile l1: # truthy while list is non-empty\n total += l1[0]\n del l1[0]\nprint(total) # 21", + "week": 2 + }, + { + "item_id": "ks-624034d573", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Walrus operator :=\nIntroduced in Python 3.8. Assigns AND evaluates to a value (unlike = which is a statement). Useful in while conditions to assign and test at once.\nWalrus in while loop\ntotal = 0\nwhile (number := int(input('give a number, or 100 to stop '))) != 100:\n if number % 2 == 1:\n total += number\nprint(total)", + "week": 2 + }, + { + "item_id": "cs-curated-hw-loops-enumerate-mark-max", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Use enumerate() to keep indices while relabeling one special case\nx = [65, 43, 1, 0, 59, 16, 86, 40, 60]\nmax_value = max(x)\nresult = {}\nfor index, value in enumerate(x):\n key = 'highest' if value == max_value else index\n result[key] = value\nprint(result)\n{0: 65, 1: 43, 2: 1, 3: 0, 4: 59, 5: 16, 'highest': 86, 7: 40, 8: 60}", + "week": 2 + }, + { + "item_id": "cs-curated-hw-loops-zip-filter-pairs", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "zip() aligns two lists so you can filter pairs into a dict\nkeys = [3, 2, 1, 4]\nvalues = [3, 37, 60, 79]\nresult = {}\nfor key, value in zip(keys, values):\n if key != value and value % 5:\n result[key] = value\nprint(result)\n{2: 37, 4: 79}", + "week": 2 + }, + { + "item_id": "cs-curated-hw-loops-market-clearing", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Flatten, sort, and zip demand/supply curves to count trades\nbuyers = {'buyer1': [24, 16, 13, 6, 5], 'buyer2': [23, 21, 19, 10, 7], 'buyer3': [21, 20, 15, 13, 10], 'buyer4': [20, 17, 9, 6, 5]}\nsellers = {'seller1': [8, 10, 14, 19, 21], 'seller2': [6, 13, 16, 21, 23], 'seller3': [8, 12, 13, 22, 23], 'seller4': [8, 9, 13, 21, 24]}\ndemand = []\nfor buyer_values in buyers.values():\n demand += buyer_values\nsupply = []\nfor seller_values in sellers.values():\n supply += seller_values\nquantity_sold = 0\nfor bid, ask in zip(sorted(demand, reverse=True), sorted(supply)):\n if bid >= ask:\n quantity_sold += 1\nprint(quantity_sold)\n10", + "week": 2 + }, + { + "item_id": "cs-curated-hw-loops-nested-pairwise-dict", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Nested loops can build pairwise results for every combination\ndef main(minimum, maximum):\n result = {}\n for first in range(minimum, maximum + 1):\n for second in range(minimum, maximum + 1):\n result[(first, second)] = first - second\n return result\n\nprint(main(2, 4))\n{(2, 2): 0, (2, 3): -1, (2, 4): -2, (3, 2): 1, (3, 3): 0, (3, 4): -1, (4, 2): 2, (4, 3): 1, (4, 4): 0}", + "week": 2 + }, + { + "item_id": "kp-1", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "In conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers).", + "week": 2 + }, + { + "item_id": "kp-1-d1", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Falsy values\n# All evaluate to False in a condition:\n[] # empty list\n() # empty tuple\n{} # empty dict\nset() # empty set\n'' # empty string\n0 # zero int\n0.0 # zero float", + "week": 2 + }, + { + "item_id": "kp-2", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Python requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().", + "week": 2 + }, + { + "item_id": "kp-2-d1", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Explicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\nprint(int('1a')) # ERROR\nprint(float('1') == 1.0) # True\nprint(float('1.0') == 1.0) # True\nprint(tuple([1,2,3]) == (1,2,3)) # True\nprint(tuple({1:3, 2:4}) == (1,2)) # True (dict->tuple gives keys)\nprint(list(range(1,5,2)) == [1,3]) # True\nprint(dict([1, 2])) # ERROR\nprint(dict([(1,3),(2,4)]) == {1:3, 2:4}) # True", + "week": 2 + }, + { + "item_id": "kp-2-d2", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Implicit conversion (Python allows with bool/numeric mix)\nprint(1 + True) # 2\nprint(1.0 + False) # 1.0\nprint('1' * 2) # '11'\nprint('1' * True) # '1'\nprint('1' * False) # ''", + "week": 2 + }, + { + "item_id": "ai-example-1", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Falsy values\n# All evaluate to False in a condition:\n[] # empty list\n() # empty tuple\n{} # empty dict\nset() # empty set\n'' # empty string\n0 # zero int\n0.0 # zero float\nIn conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers).", + "week": 2 + }, + { + "item_id": "ai-example-2", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Explicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\nprint(int('1a')) # ERROR\nprint(float('1') == 1.0) # True\nprint(float('1.0') == 1.0) # True\nprint(tuple([1,2,3]) == (1,2,3)) # True\nprint(tuple({1:3, 2:4}) == (1,2)) # True (dict->tuple gives keys)\nprint(list(range(1,5,2)) == [1,3]) # True\nprint(dict([1, 2])) # ERROR\nprint(dict([(1,3),(2,4)]) == {1:3, 2:4}) # True\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().", + "week": 2 + }, + { + "item_id": "ai-example-3", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Implicit conversion (Python allows with bool/numeric mix)\nprint(1 + True) # 2\nprint(1.0 + False) # 1.0\nprint('1' * 2) # '11'\nprint('1' * True) # '1'\nprint('1' * False) # ''\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().", + "week": 2 + }, + { + "item_id": "ai-example-4", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "str(1) versus int('1')\nprint(str(1) == '1')\nprint(int('1') == 1)", + "week": 2 + }, + { + "item_id": "ai-example-5", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Why `'1' + 2` raises `TypeError`\ntry:\n print ('1' + 2)\nexcept Exception as e:\n print(e)", + "week": 2 + }, + { + "item_id": "ai-example-6", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Why `dict([1, 2])` raises `ValueError`\ntry:\n print(dict([1, 2]))\nexcept Exception as e:\n print(e)", + "week": 2 + }, + { + "item_id": "ai-example-7", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Why `int('1a')` raises `ValueError`\ntry:\n print(int('1a') == 1)\nexcept Exception as e:\n print(e)", + "week": 2 + }, + { + "item_id": "ai-example-8", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "w2-conversion-and-truthiness-core", + "subtopic_title": "Explicit Conversion and Truthy/Falsy Rules", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Truthy list in a `while` condition\nl1 = [1, 2, 3, 4, 5, 6]\ntotal = 0\nwhile l1:\n total += l1[0]\n del l1[0]\nprint(total)\nFor numeric variables, `a += 1` updates the stored value the same way as `a = a + 1`.", + "week": 2 + }, + { + "item_id": "ks-d7e6d1b5b5", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Truthy and Falsy\nIn conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers).\nFalsy values\n# All evaluate to False in a condition:\n[] # empty list\n() # empty tuple\n{} # empty dict\nset() # empty set\n'' # empty string\n0 # zero int\n0.0 # zero float", + "week": 2 + }, + { + "item_id": "ks-d9760d8cd8", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Type conversion (explicit)\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().\nExplicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\nprint(int('1a')) # ERROR\nprint(float('1') == 1.0) # True\nprint(float('1.0') == 1.0) # True\nprint(tuple([1,2,3]) == (1,2,3)) # True\nprint(tuple({1:3, 2:4}) == (1,2)) # True (dict->tuple gives keys)\nprint(list(range(1,5,2)) == [1,3]) # True\nprint(dict([1, 2])) # ERROR\nprint(dict([(1,3),(2,4)]) == {1:3, 2:4}) # True\nImplicit conversion (Python allows with bool/numeric mix)\nprint(1 + True) # 2\nprint(1.0 + False) # 1.0\nprint('1' * 2) # '11'\nprint('1' * True) # '1'\nprint('1' * False) # ''", + "week": 2 + }, + { + "item_id": "cs-fc8bdeb969", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "type_conversion\nprint (1==1.0, 1.0 == True, 0 == False)", + "week": 2 + }, + { + "item_id": "cs-3e39a2f12f", + "card_id": "w2-conversion-and-truthiness", + "topic": "Conversion and Truthiness", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "type_conversion\nprint ('1' * 2, '1' * True, '1' * False)", + "week": 2 + }, + { + "item_id": "manual-call-vs-index", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What error do you get from `print[1]` and from `[1, 2, 3](0)`?\n`print[1]` tries to subscript a function, while `[1, 2, 3](0)` tries to call a list. Both raise `TypeError`, but for opposite reasons.\nprint[1]\n[1, 2, 3](0)", + "week": 3 + }, + { + "item_id": "manual-string-return-shape", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do you recognize that a function should `return` a string instead of `print` it?\nIf the result must be reused later, the function should `return` the string so the caller can store, combine, or print it afterwards.\ndef get_tld(url):\n parts = url.split('.')\n return parts[-1].split('/')[0]", + "week": 3 + }, + { + "item_id": "manual-list-of-dicts-loop", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do you access values when looping over a list of dictionaries?\nEach loop iteration gives one dictionary, so read fields with keys like `student['Name']` and `student['Grade']`.\nfor student in students:\n print(student['Name'], student['Grade'])", + "week": 3 + }, + { + "item_id": "kp-1", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "w3-defining-and-calling-functions-core", + "subtopic_title": "def, Calls, and Methods vs Functions", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Define with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a list and raises `TypeError`.", + "week": 3 + }, + { + "item_id": "kp-1-d1", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Basic function\ndef adder(n1, n2):\n total = n1 + n2\n return total\na = adder(1, 2)\nprint(a) # 3", + "week": 3 + }, + { + "item_id": "kp-1-d2", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Wrong bracket errors\nprint[1] # TypeError: 'function' object is not subscriptable\nl1 = [1,2,3]\nl1(1) # TypeError: 'list' object is not callable", + "week": 3 + }, + { + "item_id": "kp-2", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "w3-defining-and-calling-functions-core", + "subtopic_title": "def, Calls, and Methods vs Functions", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Methods are functions attached to objects. Some mutate the object in place, while others return a value; string methods always return a new string.", + "week": 3 + }, + { + "item_id": "kp-2-d1", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Method on immutable — must capture return value\ns1 = 'UVA Amsterdam'\ns1 = s1.upper() # CORRECT — captures new string\ns1.upper() # WRONG — result is lost, s1 unchanged", + "week": 3 + }, + { + "item_id": "kp-2-d2", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Method on mutable — changes in place vs returns value\nl1 = [3, 1, 2]\nl1.sort() # changes l1 in place, returns None\nprint(l1) # [1, 2, 3]\nprint(l1.index(2)) # 1 (returns index, doesn't change l1)", + "week": 3 + }, + { + "item_id": "kp-3", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "w3-defining-and-calling-functions-core", + "subtopic_title": "def, Calls, and Methods vs Functions", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Function skeleton: `def f(x): return result`. Define with `def ...`, call with `()`, and use `[]` only for indexing.", + "week": 3 + }, + { + "item_id": "ai-example-1", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "w3-defining-and-calling-functions-core", + "subtopic_title": "def, Calls, and Methods vs Functions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Define, call, and return a value\ndef adder(n1, n2):\n total = n1 + n2\n return total\na = adder(1, 2)\nprint(a) # 3\nDefine with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a list and raises `TypeError`.\n3", + "week": 3 + }, + { + "item_id": "ai-example-2", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "w3-defining-and-calling-functions-core", + "subtopic_title": "def, Calls, and Methods vs Functions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Wrong bracket errors\nprint[1] # TypeError: 'function' object is not subscriptable\nl1 = [1,2,3]\nl1(1) # TypeError: 'list' object is not callable\nDefine with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a list and raises `TypeError`.\nTypeError\nTypeError", + "week": 3 + }, + { + "item_id": "ai-example-3", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "w3-defining-and-calling-functions-core", + "subtopic_title": "def, Calls, and Methods vs Functions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Method on immutable — must capture return value\ns1 = 'UVA Amsterdam'\ns1 = s1.upper() # CORRECT — captures new string\ns1.upper() # WRONG — result is lost, s1 unchanged\nMethods are functions attached to objects. Some mutate the object in place, while others return a value; string methods always return a new string.\nUVA AMSTERDAM", + "week": 3 + }, + { + "item_id": "ai-example-4", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "w3-defining-and-calling-functions-core", + "subtopic_title": "def, Calls, and Methods vs Functions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Method on mutable — changes in place vs returns value\nl1 = [3, 1, 2]\nl1.sort() # changes l1 in place, returns None\nprint(l1) # [1, 2, 3]\nprint(l1.index(2)) # 1 (returns index, doesn't change l1)\nMethods are functions attached to objects. Some mutate the object in place, while others return a value; string methods always return a new string.\n[1, 2, 3]\n1", + "week": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following code segments will achieve what you want?\nA\nB\nC\nD\nA\nWhen iterating over a list of dictionaries, each iteration yields a dictionary. You access values using keys like student['Name']. Options B and D fail because lists do not have an .items() method.", + "week": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?\nA\nB\nC\nD\nA\nThis is a standard dictionary comprehension. Option B is a list comprehension, Option C is a set comprehension, and Option D swaps keys and values.", + "week": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What will be printed by the function calls in the main function provided?\nA\nB\nC\nD\nD\nThe function checks if all elements in the input list are either all empty or all non-empty. For the sets and lists provided, they are consistent within each call.", + "week": 3 + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?\na\nb\nc\nd\na\nOption A splits the entire URL by '.', so the last element will be 'html' (from 'bachelors.html'). Then splitting 'html' by '/' and taking the first element still results in 'html', not the top-level domain 'nl'. Therefore, it does NOT achieve what is intended.", + "week": 3 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) at various places.\n\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\n\nWhich of the following code segments does not achieve what you want?\na\nb\nc\nd\na\nStrings in Python are immutable. The `replace()` method returns a new string, it does not modify the original string in place. Because Option A does not reassign the result of `number.replace(\"-\", \"\")` or return it directly, it returns the original, unmodified string.", + "week": 3 + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?\na\nb\nc\nd\na\nOption A correctly removes spaces, converts strings to lower case, transforms them to lists, and sorts the lists using sorted() before comparing them. Option B is incorrect because strings do not have a .sort() method. Option C is incorrect because list.sort() operates in-place and returns None, so it would compare None == None. Option D is incorrect because sorted() returns a list, and lists do not have a .replace() or .lower() method.", + "week": 3 + }, + { + "item_id": "ks-e09d7f145b", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Function definition and calling\ndef keyword, function name, parameters in parentheses, colon, indented body. Call with round brackets (). Using [] gives TypeError 'not subscriptable'. Using [] on a list with () gives TypeError 'not callable'.\nBasic function\ndef adder(n1, n2):\n total = n1 + n2\n return total\na = adder(1, 2)\nprint(a) # 3\nWrong bracket errors\nprint[1] # TypeError: 'function' object is not subscriptable\nl1 = [1,2,3]\nl1(1) # TypeError: 'list' object is not callable", + "week": 3 + }, + { + "item_id": "ks-ab66f3bab6", + "card_id": "w3-defining-and-calling-functions", + "topic": "Defining and Calling Functions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Methods vs functions\nMethods are functions attached to objects. Calling obj.method() is equivalent to Class.method(obj). For mutable objects: some methods CHANGE the object (e.g. list.sort()), some RETURN a value (e.g. list.index()). For immutable objects: methods always return a new value (can't change the object itself). COMMON ERROR: s1.upper() on strings — you must do s1 = s1.upper() to save the result.\nMethod on immutable — must capture return value\ns1 = 'UVA Amsterdam'\ns1 = s1.upper() # CORRECT — captures new string\ns1.upper() # WRONG — result is lost, s1 unchanged\nMethod on mutable — changes in place vs returns value\nl1 = [3, 1, 2]\nl1.sort() # changes l1 in place, returns None\nprint(l1) # [1, 2, 3]\nprint(l1.index(2)) # 1 (returns index, doesn't change l1)", + "week": 3 + }, + { + "item_id": "aiq-1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Condition flow and branch result\nExam • midterm_2024 • Q1\nConsider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?", + "week": 3 + }, + { + "item_id": "aiq-2", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7", + "week": 3 + }, + { + "item_id": "aiq-3", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. Correct: d.\nExam • extra_practice • Q9", + "week": 3 + }, + { + "item_id": "aiq-4", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None.", + "week": 3 + }, + { + "item_id": "aiq-5", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple", + "week": 3 + }, + { + "item_id": "kp-1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Returns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.", + "week": 3 + }, + { + "item_id": "kp-1-d1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Returning a tuple (multiple values)\ndef powers(n1):\n return n1 ** 2, n1 ** 3 # returns a tuple\npower2, power3 = powers(3)\nprint(power2, power3) # 9 27", + "week": 3 + }, + { + "item_id": "kp-2", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "If a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None:", + "week": 3 + }, + { + "item_id": "kp-2-d1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Implicit None return\ndef adder(n1, n2):\n if type(n1) == type(n2) == int:\n total = n1 + n2\n return total\na = adder('1', 2) # Returns None (no return hit)\nprint(a) # None", + "week": 3 + }, + { + "item_id": "kp-3", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "(1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x", + "week": 3 + }, + { + "item_id": "kp-3-d1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "1-element tuple gotcha\nt1 = (1)\nprint(type(t1) == tuple) # False\nprint(type(t1) == int) # True\nt1 = (1,) # correct 1-element tuple\nt1 = 1, # also correct\nx, y = y, x # swap using tuple unpacking", + "week": 3 + }, + { + "item_id": "kp-4", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Does nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this.", + "week": 3 + }, + { + "item_id": "kp-4-d1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "pass as stub\ndef adder(n1, n2):\n if type(n1) == int and type(n2) == int:\n result = n1 + n2\n else:\n pass # placeholder — won't cause IndentationError\n return result", + "week": 3 + }, + { + "item_id": "ai-example-1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Returning a tuple (multiple values)\ndef powers(n1):\n return n1 ** 2, n1 ** 3 # returns a tuple\npower2, power3 = powers(3)\nprint(power2, power3) # 9 27\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.", + "week": 3 + }, + { + "item_id": "ai-example-2", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Implicit None return\ndef adder(n1, n2):\n if type(n1) == type(n2) == int:\n total = n1 + n2\n return total\na = adder('1', 2) # Returns None (no return hit)\nprint(a) # None\nIf a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None:", + "week": 3 + }, + { + "item_id": "ai-example-3", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "1-element tuple gotcha\nt1 = (1)\nprint(type(t1) == tuple) # False\nprint(type(t1) == int) # True\nt1 = (1,) # correct 1-element tuple\nt1 = 1, # also correct\nx, y = y, x # swap using tuple unpacking\n(1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x", + "week": 3 + }, + { + "item_id": "ai-example-4", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "pass as stub\ndef adder(n1, n2):\n if type(n1) == int and type(n2) == int:\n result = n1 + n2\n else:\n pass # placeholder — won't cause IndentationError\n return result\nDoes nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this.", + "week": 3 + }, + { + "item_id": "ai-example-5", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function return value and trace\ndef adder(n1, n2):\n return n1 + n2\na = adder(1,2)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3 + }, + { + "item_id": "ai-example-6", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function return value and trace\ndef adder(n1, n2):\n total = n1 + n2\na = adder(1, 2)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3 + }, + { + "item_id": "ai-example-7", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function return value and trace\ndef powers(n1):\n return n1 ** 2, n1 ** 3\na = powers(3)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3 + }, + { + "item_id": "ai-example-8", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function return value and trace\ndef powers(n1):\n return n1 ** 2, n1 ** 3\npower2, power3 = powers(3)\nprint(power2, power3)\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3 + }, + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None.", + "week": 3 + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`.", + "week": 3 + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict.", + "week": 3 + }, + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None", + "week": 3 + }, + { + "item_id": "exam-extra_practice-7-w3-return-behavior", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "def multiply(num1, num2):\n\tglobal result\n\tresult = num1 * num2\n\nprint(multiply(2, 3))\nprint(result)\na\nb\nc\nd\nb\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.", + "week": 3 + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\nb\nc\nd\nd\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. Correct: d.", + "week": 3 + }, + { + "item_id": "ks-00b2983ca8", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Return statement\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.\nReturning a tuple (multiple values)\ndef powers(n1):\n return n1 ** 2, n1 ** 3 # returns a tuple\npower2, power3 = powers(3)\nprint(power2, power3) # 9 27", + "week": 3 + }, + { + "item_id": "ks-14515a5856", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Implicit return — None\nIf a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None:\nImplicit None return\ndef adder(n1, n2):\n if type(n1) == type(n2) == int:\n total = n1 + n2\n return total\na = adder('1', 2) # Returns None (no return hit)\nprint(a) # None", + "week": 3 + }, + { + "item_id": "ks-d1a2d7739d", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Single-element tuple\n(1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x\n1-element tuple gotcha\nt1 = (1)\nprint(type(t1) == tuple) # False\nprint(type(t1) == int) # True\nt1 = (1,) # correct 1-element tuple\nt1 = 1, # also correct\nx, y = y, x # swap using tuple unpacking", + "week": 3 + }, + { + "item_id": "ks-db93da9e3e", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "pass keyword\nDoes nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this.\npass as stub\ndef adder(n1, n2):\n if type(n1) == int and type(n2) == int:\n result = n1 + n2\n else:\n pass # placeholder — won't cause IndentationError\n return result", + "week": 3 + }, + { + "item_id": "manual-local-name", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Why does `print(n1)` fail outside `def adder(n1, n2): ...`?\nParameter names are local to the function body, so they do not exist in the global scope after the call finishes.\ndef adder(n1, n2):\n return n1 + n2\n\nadder(1, 2)\nprint(n1)", + "week": 3 + }, + { + "item_id": "manual-unboundlocal", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Why can assigning to a name inside a function cause `UnboundLocalError`?\nIf a function assigns to a name anywhere in its body, Python treats that name as local throughout the function unless you declare it `global` or `nonlocal`.\nb = 1\n\ndef main(a):\n b = b\n return a", + "week": 3 + }, + { + "item_id": "manual-global", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "When do you need `global`?\nUse `global name` only when the function should rebind a global variable; simple reads of a global name do not need it.\nn1 = 1\n\ndef changer():\n global n1\n n1 = n1 + 1", + "week": 3 + }, + { + "item_id": "kp-manual-scope-local", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Names assigned inside a function are local by default, including parameter names.", + "week": 3 + }, + { + "item_id": "kp-manual-scope-unbound", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "If a function assigns to a name anywhere, Python treats that name as local throughout that function unless `global` or `nonlocal` says otherwise.", + "week": 3 + }, + { + "item_id": "kp-manual-scope-global", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `global x` only when the function should rebind the global name `x`; mutating an object passed in as an argument does not require `global`.", + "week": 3 + }, + { + "item_id": "manual-scope-local-name", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "w3-scope-core", + "subtopic_title": "Global vs Local Names and Scope Errors", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Parameter names stay local to the function\ndef adder(n1, n2):\n return n1 + n2\n\nprint(adder(1, 2))\nprint(n1)\nAfter the function call, `n1` and `n2` do not exist outside the function body.\n3\nNameError", + "week": 3 + }, + { + "item_id": "manual-scope-unbound", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "w3-scope-core", + "subtopic_title": "Global vs Local Names and Scope Errors", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Assignment makes the name local\nb = 1\n\ndef main(a):\n b = b\n return a\n\nprint(main(1))\nBecause `b` is assigned inside `main`, Python treats it as local before the `b = b` line runs.\nUnboundLocalError", + "week": 3 + }, + { + "item_id": "manual-scope-global-change", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "w3-scope-core", + "subtopic_title": "Global vs Local Names and Scope Errors", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Use `global` to rebind a global name\nn1 = 1\n\ndef changer():\n global n1\n n1 = n1 + 1\n\nchanger()\nprint(n1)\nWith `global n1`, the assignment updates the global name instead of creating a local one.\n2", + "week": 3 + }, + { + "item_id": "manual-scope-rebind-parameter", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "w3-scope-core", + "subtopic_title": "Global vs Local Names and Scope Errors", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Rebinding a parameter does not change the caller's name\ndef changer(n1):\n n1 = n1 + 1\n return n1\n\na = 1\na = changer(a)\nprint(a)\nThe function works with its local parameter; the caller changes only because the returned value is assigned back to `a`.\n2", + "week": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope.", + "week": 3 + }, + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?\na\nb\nc\nd\nb\nThe global variable 'a' is accessible inside the inner function without error. The code evaluates to inner(5) * 3 = (1 + 5 + 4) * 3 = 30.", + "week": 3 + }, + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called.", + "week": 3 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope.", + "week": 3 + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The code will throw an UnboundLocalError or NameError when evaluating var_1 in 'var_2 = var_1 - var'.", + "week": 3 + }, + { + "item_id": "exam-extra_practice-2-w3-scope", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modified to 3, print 3, then print val2=3. Output: 3,3. Option c: func3 creates local val3=3, prints 3. Global val3=2 unchanged, prints 2. Output: 3,2. Matches! Option d: innerfunc() called outside func4 scope — NameError. Correct: c.", + "week": 3 + }, + { + "item_id": "exam-midterm_2023-3-w3-scope", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which other program will give the same output as the following code snippet?", + "week": 3 + }, + { + "item_id": "exam-midterm_2024-5-w3-scope", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which other program will produce the same output as the following code snippet?", + "week": 3 + }, + { + "item_id": "ks-2a6510492d", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local at call time, BEFORE executing the body — so if you assign to a name ANYWHERE in a function, that name is local throughout the function (even before the assignment line). Use 'global' keyword to override (but avoid it).\nLocal name not accessible outside\ndef adder(n1, n2):\n return n1 + n2\nadder(1, 2)\nprint(n1) # NameError: name 'n1' is not defined\nUnboundLocalError trap — local shadows global even before assignment\ndef main(a):\n b = b # ERROR: Python sees b assigned in function -> local\n return a # but local b has no value yet\nb = 1\nprint(main(1)) # UnboundLocalError\nglobal keyword\ndef changer():\n global n1\n n1 = n1 + 1\nn1 = 1\nchanger()\nprint(n1) # 2\nBetter pattern: avoid global\ndef changer(n1):\n n1 = n1 + 1\n return n1\na = 1\na = changer(a)\nprint(a) # 2\nMutable parameter is the SAME object\ndef adder(l2):\n result = 0\n while l2:\n result += l2.pop()\n return result\nl1 = [1, 2, 3, 4, 5]\ntotal = adder(l1)\nprint(f'The sum of {l1} = {total}') # The sum of [] = 15 !!!\n# l1 is empty because l2 and l1 refer to the SAME list object\nFix: copy mutable arg at start of function\ndef adder(l2):\n l2 = l2[:] # make a copy\n result = 0\n while l2:\n result += l2.pop()\n return result", + "week": 3 + }, + { + "item_id": "aiq-1", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Mutable default argument\nCheck whether the method mutates the list in place and what the list looks like after each call.\nMutable default argument", + "week": 3 + }, + { + "item_id": "aiq-2", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Mutable arguments\nMutating a passed list changes the caller's object; rebinding the parameter does not.\nMutable arguments", + "week": 3 + }, + { + "item_id": "aiq-3", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)", + "week": 3 + }, + { + "item_id": "aiq-4", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we call the function as:\nprint_info('John', 30, city = 'New York', job = 'software engineer')\nthen it should return the dictionary:\n{'name' = 'John', 'age' = 30, 'city' = 'New York', 'job' = 'software engineer'}\nWhich of the following code snippets will do what you want?", + "week": 3 + }, + { + "item_id": "aiq-5", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-value pairs:\namount: the number of the integers from the input list\nsmallest: the smallest integer from the input list\nlargest: the largest integer from the input list\ntotal: the sum of all integers from the input list\nWhich of the following functions will achieve what you need?", + "week": 3 + }, + { + "item_id": "aiq-6", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function", + "week": 3 + }, + { + "item_id": "aiq-7", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Mutable parameter sharing\nWhen mutable object passed as argument, parameter and argument point to SAME object — mutations inside function affect original", + "week": 3 + }, + { + "item_id": "kp-1", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Prefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.", + "week": 3 + }, + { + "item_id": "kp-1-d1", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "*args usage\ndef adder(*args):\n result = 0\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15", + "week": 3 + }, + { + "item_id": "kp-1-d2", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Mix defined and *args\ndef adder(n1, n2, *args):\n result = n1 + n2\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15", + "week": 3 + }, + { + "item_id": "kp-2", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Arguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.", + "week": 3 + }, + { + "item_id": "kp-2-d1", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Keyword arguments\ndef calc(first, second, third, fourth, fifth, sixth):\n return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth\nprint(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63", + "week": 3 + }, + { + "item_id": "kp-2-d2", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "**kwargs\ndef calc(**kwargs):\n return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third']\nprint(calc(third=4, second=2, first=3))", + "week": 3 + }, + { + "item_id": "kp-3", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Default values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.", + "week": 3 + }, + { + "item_id": "kp-3-d1", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Default value\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3)) # 6 (uses default second=2)\nprint(multiplier(3, 3)) # 9\nprint(multiplier(2, second=3)) # 6", + "week": 3 + }, + { + "item_id": "kp-3-d2", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Mutable default BUG\ndef main(addition, l1=[]):\n l1.append(addition)\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [2, 3] ← BUG: l1 persists!", + "week": 3 + }, + { + "item_id": "ai-example-1", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "*args usage\ndef adder(*args):\n result = 0\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15\nPrefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.", + "week": 3 + }, + { + "item_id": "ai-example-2", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Mix defined and *args\ndef adder(n1, n2, *args):\n result = n1 + n2\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15\nPrefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.", + "week": 3 + }, + { + "item_id": "ai-example-3", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Keyword arguments\ndef calc(first, second, third, fourth, fifth, sixth):\n return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth\nprint(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63\nArguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.", + "week": 3 + }, + { + "item_id": "ai-example-4", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function return value and trace\ndef calc(**kwargs):\n return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third']\nprint(calc(third=4, second=2, first=3))\nArguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.", + "week": 3 + }, + { + "item_id": "ai-example-5", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Default value\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3)) # 6 (uses default second=2)\nprint(multiplier(3, 3)) # 9\nprint(multiplier(2, second=3)) # 6\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.", + "week": 3 + }, + { + "item_id": "ai-example-6", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Mutable default BUG\ndef main(addition, l1=[]):\n l1.append(addition)\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [2, 3] ← BUG: l1 persists!\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.", + "week": 3 + }, + { + "item_id": "ai-example-7", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function return value and trace\ndef adder(n1, n2):\n return n1 + n2\nprint(adder(1, 2))\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3 + }, + { + "item_id": "ai-example-8", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function return value and trace\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3))\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which of the following function calls would return the number 30 as a result?\nA\nB\nC\nD\nC\nThe first call sums (6+7+8+9)=30. The second call sums (1+4+9+16)=30.", + "week": 3 + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run for `i` from 1 to 10 inclusive, resulting in a list of 10 formatted multiplication strings.", + "week": 3 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?\na\nb\nc\nd\nb\nOption B correctly iterates over the values of the kwargs dictionary and adds each price to the total. Option A would cause a TypeError because it tries to add a string key ('item') to an integer.", + "week": 3 + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\nWhich of the following functions will return the intended value?\na\nb\nc\nd\nb\nOption B correctly iterates through the values of the `kwargs` dictionary using `kwargs.values()` and sums them. Option A tries to add the keys (`item`), which are strings. Option C tries to unpack keys into two variables, which will fail or iterate through string characters incorrectly.", + "week": 3 + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB 40\n45\nThe code will result in TypeError because there is a missing argument.\nC 25\n35\n35\nD All three lines of code will result in TypeError because there is a missing argument.", + "week": 3 + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments.", + "week": 3 + }, + { + "item_id": "exam-midterm_2024-13-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.", + "week": 3 + }, + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, factor=3)\nmultiply(3, 4)\nmultiply()\nA def multiply(*args, factor=2):\ntotal = args[0]\nfor num in args:\ntotal *= num\nreturn total * factor\nB def multiply(*args, factor=2):\nif not args:\nreturn 0\ntotal = args[0]\nfor num in args[1:]:\ntotal *= num\nreturn total * factor\nC Both functions will return the same values.\nD Neither functions will return the same values.", + "week": 3 + }, + { + "item_id": "ks-40fee04740", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "*args — undefined number of positional arguments\nPrefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.\n*args usage\ndef adder(*args):\n result = 0\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15\nMix defined and *args\ndef adder(n1, n2, *args):\n result = n1 + n2\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15", + "week": 3 + }, + { + "item_id": "ks-f5d65c7e89", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Keyword arguments and **kwargs\nArguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.\nKeyword arguments\ndef calc(first, second, third, fourth, fifth, sixth):\n return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth\nprint(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63\n**kwargs\ndef calc(**kwargs):\n return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third']\nprint(calc(third=4, second=2, first=3))\nMixed: positional + *args + **kwargs\ndef calc(first, second, *args, **kwargs):\n return first + second*2 + args[0]*3 + args[1]*4 + 5*kwargs['fifth'] + 6*kwargs['sixth']\nprint(calc(3, 2, 4, 1, sixth=5, fifth=2)) # 63", + "week": 3 + }, + { + "item_id": "ks-d26b85265c", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Default arguments\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.\nDefault value\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3)) # 6 (uses default second=2)\nprint(multiplier(3, 3)) # 9\nprint(multiplier(2, second=3)) # 6\nMutable default BUG\ndef main(addition, l1=[]):\n l1.append(addition)\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [2, 3] ← BUG: l1 persists!\nMutable default FIX — use None\ndef main(addition, l1=None):\n if l1 is None:\n l1 = []\n l1 += [addition]\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [3] ← correct", + "week": 3 + }, + { + "item_id": "aiq-1", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • trial_midterm • Q17\nA def squared_function(x):\nreturn x**2\nprint(squared_function([1, 2, 3]))\nB print(list(map(lambda x: x**2, [1, 2, 3])))\nC def squared_function(x):\nreturn x**2\nprint(list(map(squared_function, [1, 2, 3])))\nD squared_numbers = lambda x: x**2\nprint([squared_numbers(1), squared_numbers(2), squared_numbers(3)])", + "week": 3 + }, + { + "item_id": "aiq-2", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\nthen it should return the list:\n[-10, -9, 7, 5, 4, -3, 2]\nWhich of the following functions will give you the correct output?", + "week": 3 + }, + { + "item_id": "aiq-3", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such as:\nmy_list = [0, 1, 2, 3, 4]\nyou want to print:\n[0, 0]\n[1, 1]", + "week": 3 + }, + { + "item_id": "aiq-5", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: ", + "week": 3 + }, + { + "item_id": "kp-1", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Functions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).", + "week": 3 + }, + { + "item_id": "kp-1-d1", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Function factory\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\nadd4 = function_factory(4)\nadd5 = function_factory(5)\nprint(add4(3)) # 7\nprint(add5(3)) # 8", + "week": 3 + }, + { + "item_id": "kp-1-d2", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nTool | Returns | Best for\nmap(f, seq) | lazy transformed iterable | same-length transform\nfilter(f, seq) | lazy filtered iterable | keep matching items\nsorted(seq, key=...) | new sorted list | comparison key\nlambda x: ... | anonymous function | small inline transform", + "week": 3 + }, + { + "item_id": "kp-2", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Anonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.", + "week": 3 + }, + { + "item_id": "kp-2-d1", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Lambda basics\nadd_two = lambda x, y: x + y\nprint(add_two(1, 2)) # 3\n# Equivalent to:\ndef add_two(x, y):\n return x + y", + "week": 3 + }, + { + "item_id": "kp-2-d2", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "map() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12]\n# Need list() to convert map object to list", + "week": 3 + }, + { + "item_id": "kp-3", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "def function_factory(increment): def adder(n1): return n1 + increment return adder add4 = function_factory(4) add5 = function_factory (5) print(add4(3)) print(add5(3))", + "week": 3 + }, + { + "item_id": "ai-example-1", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Function factory\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\nadd4 = function_factory(4)\nadd5 = function_factory(5)\nprint(add4(3)) # 7\nprint(add5(3)) # 8\nFunctions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).", + "week": 3 + }, + { + "item_id": "ai-example-2", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Lambda basics\nadd_two = lambda x, y: x + y\nprint(add_two(1, 2)) # 3\n# Equivalent to:\ndef add_two(x, y):\n return x + y\nAnonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.", + "week": 3 + }, + { + "item_id": "ai-example-3", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "map() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12]\n# Need list() to convert map object to list\nAnonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.", + "week": 3 + }, + { + "item_id": "ai-example-4", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Elementwise transformation with `map`/`lambda`\nprint((lambda x, y: 2*x*y)(4, 3))\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.", + "week": 3 + }, + { + "item_id": "ai-example-5", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "sorted_key\nl1 = ['a', 'B', 'c']\nprint(sorted(l1))", + "week": 3 + }, + { + "item_id": "ai-example-6", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "sorted_key\nl1 = ['ad', 'dc', 'ce']\nprint(sorted(l1))", + "week": 3 + }, + { + "item_id": "ai-example-7", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "sorted_builtins\nl1 = ['aaa', 'bb', 'c']\nprint(sorted(l1))", + "week": 3 + }, + { + "item_id": "ai-example-8", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "w3-higher-order-patterns-core", + "subtopic_title": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "sorted_builtins\nl1 = ['aaa', 'bb', 'c']\nprint(sorted(l1, key=len))", + "week": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))\nA\nB\nC\nD\nD\nlist_1[0](1, 2) is 1 + 2 = 3. list_1[1](1, 2) is 1 * 2 = 2. 3 ** 2 = 9.", + "week": 3 + }, + { + "item_id": "exam-midterm_2023-11-w3-higher-order-patterns", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nThe function should return a new list, in which the elements are sorted from highest to lowest based on their absolute values.", + "week": 3 + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such as:\nmy_list = [0, 1, 2, 3, 4]\nyou want to print:\n[0, 0]\n[1, 1]\n[4, 8]\n[9, 27]\n[16, 64]\nWhich of the following blocks of codes works as intended?\nA funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x(i), funcs)\nprint(list(results))\nB funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x[i], funcs)\nprint(list(results))\nC funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x(i), funcs)\nprint(results)\nD funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x[i], funcs)\nprint(results)", + "week": 3 + }, + { + "item_id": "exam-trial_midterm-17-w3-higher-order-patterns", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nWhich block of code prints something different than the other blocks print?", + "week": 3 + }, + { + "item_id": "exam-midterm_2024-19-w3-higher-order-patterns", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nWhich block of code prints something different than the other blocks print?", + "week": 3 + }, + { + "item_id": "ks-f069ee6a0b", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Nested functions and function factories\nFunctions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).\nFunction factory\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\nadd4 = function_factory(4)\nadd5 = function_factory(5)\nprint(add4(3)) # 7\nprint(add5(3)) # 8", + "week": 3 + }, + { + "item_id": "ks-58858d6d96", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Lambda functions\nAnonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.\nLambda basics\nadd_two = lambda x, y: x + y\nprint(add_two(1, 2)) # 3\n# Equivalent to:\ndef add_two(x, y):\n return x + y\nmap() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12]\n# Need list() to convert map object to list\nfilter() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(filter(lambda x: not x % 2, l1))) # [2, 4, 6] (even numbers)\nreduce() with lambda\nfrom functools import reduce\nl1 = [1, 2, 3, 4, 5, 6]\nprint(reduce(lambda x, y: x*y, l1)) # 720 (product)\n# reduce with initial value:\nl1 = ['aaa', 'baab', 'c']\nprint(reduce(lambda x, y: x + y.count('a'), l1, 0)) # 5\nsorted() with key lambda\nl1 = ['aaa', 'c', 'baab']\nprint(sorted(l1)) # ['aaa', 'baab', 'c']\nprint(sorted(l1, key=lambda x: x.count('a'))) # ['c', 'baab', 'aaa']\nprint(sorted(l1, key=len)) # ['c', 'aaa', 'baab']\n\nd = {'a': 2, 'b': 1}\nprint(max(d.items())) # ('b', 1) ← compares tuples\nprint(max(d.items(), key=lambda x: x[1])) # ('a', 2) ← by value", + "week": 3 + }, + { + "item_id": "ks-994a4083e3", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "function_factories\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\n\nadd4 = function_factory(4)\nadd5 = function_factory (5)\n\nprint(add4(3))\nprint(add5(3))", + "week": 3 + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "additional", + "selection_kind": "source", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the following code snippets achieve what you want?\na\nb\nc\nd\nb\nOption a produces both (5,6) and (6,5) — it doesn't ensure uniqueness. Option b iterates up to target//2, so each pair is only considered once. For target=11, range(0,6): checks 0,1,2,3,4,5. Finds: 2+9,3+8,4+7,5+6 — unique pairs. Option b works as intended. Option a doesn't meet the uniqueness requirement. Correct: b.", + "week": 3 + }, + { + "item_id": "cs-curated-hw-hof-nested-helper-hhi", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "A nested helper can hide repeated domain math inside one outer function\ndef main(sales_before_entry):\n def calculate_hhi(sales_volumes):\n total_sales = sum(sales_volumes)\n return sum(round(100 * volume / total_sales) ** 2 for volume in sales_volumes)\n\n before = calculate_hhi(sales_before_entry)\n after = calculate_hhi(sales_before_entry + [40])\n return before - after\n\nprint(main([47, 21, 27, 29, 11, 6, 18]))\n224", + "week": 3 + }, + { + "item_id": "aiq-1", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Given s1 = 'abcd', which code fragment correctly updates s1 to 'Abcd'?\nStrings are immutable. s1.capitalize() returns a new string, so you must assign that result back to the name s1.\nString Methods", + "week": 4 + }, + { + "item_id": "manual-string-immutability", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Why does `s[0] = 'A'` fail?\nStrings are immutable, so you must build a new string such as `s = 'A' + s[1:]` instead of assigning by index.\ns = 'abcd'\ns = 'A' + s[1:]", + "week": 4 + }, + { + "item_id": "manual-string-escapes", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do you include quotes or a newline inside a string literal?\nPick the other quote style or escape the inner quote; use `\\n` for a newline.\nprint(\"it's\")\nprint('He said \"hi\"')\nprint(\"Line 1\\nLine 2\")", + "week": 4 + }, + { + "item_id": "kp-1", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Strings are immutable: methods like `.upper()` and `.replace()` return a new string, so assign the result back if you want the change to stick.", + "week": 4 + }, + { + "item_id": "kp-1-d1", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Attempting to change a string\ns1 = 'abcd'\ns1.capitalize() # Returns 'Abcd'\nprint(s1) # Still prints 'abcd'", + "week": 4 + }, + { + "item_id": "kp-1-d2", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nForm | What it means | Exam use\n'...'/\"...\" | basic literals | choose quote style\n\\n / \\t | newline / tab | predict printed output\nr'...' | raw string | slashes stay literal\ns[i:j:k] | string slicing | same rules as sequences", + "week": 4 + }, + { + "item_id": "kp-2", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Escape sequences: `\\n` newline, `\\t` tab, and `\\'` or `\\\"` for literal quotes.", + "week": 4 + }, + { + "item_id": "kp-2-d1", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Newlines and tabs\nprint('Line 1\\nLine 2\\tTabbed')\nprint(\"It\\'s a string\")", + "week": 4 + }, + { + "item_id": "kp-3", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Strings are immutable: `s[0] = 'A'` fails, so rebuild or rebind, for example `s = 'A' + s[1:]`.", + "week": 4 + }, + { + "item_id": "ai-example-1", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Methods return new strings\ns1 = 'abcd'\ns1.capitalize() # Returns 'Abcd'\nprint(s1) # Still prints 'abcd'\nStrings are immutable: methods like `.upper()` and `.replace()` return a new string, so assign the result back if you want the change to stick.\nabcd", + "week": 4 + }, + { + "item_id": "ai-example-2", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Newlines and tabs\nprint('Line 1\\nLine 2\\tTabbed')\nprint(\"It\\'s a string\")\nEscape sequences: `\\n` newline, `\\t` tab, and `\\'` or `\\\"` for literal quotes.", + "week": 4 + }, + { + "item_id": "ai-example-4", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Filter uppercase letters with a helper function\ndef my_isupper(s1):\n for el in s1:\n if el not in \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\":\n return False\n return True \n\nx = \"Harry Potter and the Philosopher's Stone\"\ny = ''\nfor i in x:\n if my_isupper(i):\n y += i\nprint(y)\nTrace the loop character by character and keep only the uppercase letters that satisfy the test.\nHPPS", + "week": 4 + }, + { + "item_id": "ai-example-8", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`len(s)` counts characters\na = 'adbc'\nprint(len(a))\nCount every character in the string, including letters, spaces, and punctuation if they are present.\n4", + "week": 4 + }, + { + "item_id": "manual-string-literals-example", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "w4-string-fundamentals-core", + "subtopic_title": "Quotes, Escape Characters, and Immutability", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Quotes and newline escapes\nprint(\"it's\")\nprint('He said \"hi\"')\nprint(\"Line 1\\nLine 2\")\nUse matching quotes or escape the inner quote; `\\n` inserts a newline.\nit's\nHe said \"hi\"\nLine 1\nLine 2", + "week": 4 + }, + { + "item_id": "ks-b734a22f46", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "String Immutability\nStrings in Python are immutable, meaning they cannot be changed in place. Methods like upper() or replace() return a new string object rather than modifying the original.\nAttempting to change a string\ns1 = 'abcd'\ns1.capitalize() # Returns 'Abcd'\nprint(s1) # Still prints 'abcd'", + "week": 4 + }, + { + "item_id": "ks-309158a68c", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Escape Characters\nSpecial characters like newlines (\\n), tabs (\\t), or literal quotes can be included using the backslash (\\).\nNewlines and tabs\nprint('Line 1\\nLine 2\\tTabbed')\nprint(\"It\\'s a string\")", + "week": 4 + }, + { + "item_id": "cs-e7bc165499", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "def main(a, b):\ndef main(a, b):\n return f'''The first number is: {a:04d}\nThe second number is: {b:04d}\nThe product is: {a * b:04d}'''\nprint(main(7,13))\nThe first number is: 0007\nThe second number is: 0013\nThe product is: 0091", + "week": 4 + }, + { + "item_id": "cs-14245b8c1f", + "card_id": "w4-string-fundamentals", + "topic": "String Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "def my_isupper(s1):\ndef my_isupper(s1):\n for el in s1:\n if el not in \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\":\n return False\n return True \n\nx = \"Harry Potter and the Philosopher's Stone\"\ny = ''\nfor i in x:\n if my_isupper(i):\n y += i\nprint(y)\nHPPS", + "week": 4 + }, + { + "item_id": "aiq-2", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing", + "week": 4 + }, + { + "item_id": "aiq-5", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy", + "week": 4 + }, + { + "item_id": "aiq-6", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "range() and slicing both exclusive at stop\nrange(1,10,3)→[1,4,7] not including 10; l[2:7] goes up to but not including index 7", + "week": 4 + }, + { + "item_id": "manual-find-vs-index", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What is the difference between `s.find(x)` and `s.index(x)` when `x` is missing?\n`find` returns `-1`; `index` raises `ValueError`.\ns = 'banana'\nprint(s.find('x'))\nprint(s.index('x')) # ValueError", + "week": 4 + }, + { + "item_id": "kp-1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Both find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError.", + "week": 4 + }, + { + "item_id": "kp-1-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Behavior when substring is missing\ns = 'abc'\nprint(s.find('z')) # -1\n# print(s.index('z')) # Raises ValueError", + "week": 4 + }, + { + "item_id": "kp-1-d2", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nMethod | Returns | Trap\ns.find(x) | index or -1 | never raises\ns.index(x) | index | raises if missing\ns.replace(a, b) | new string | strings are immutable\nsep.join(seq) | new joined string | separator is the caller", + "week": 4 + }, + { + "item_id": "kp-2", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Slicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string.", + "week": 4 + }, + { + "item_id": "kp-2-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Slicing examples\ns = '01234567'\nprint(s[::4]) # '04'\nprint(s[::-2]) # '7531'", + "week": 4 + }, + { + "item_id": "kp-3", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "The join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator.", + "week": 4 + }, + { + "item_id": "kp-3-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Joining a list into a string\nwords = ['a', 'b', 'c']\nprint('-'.join(words)) # 'a-b-c'\nprint(''.join(words)) # 'abc'", + "week": 4 + }, + { + "item_id": "kp-4", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Replaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements.", + "week": 4 + }, + { + "item_id": "kp-4-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Limiting replacements\ns = 'aaaa'\nprint(s.replace('a', 'b', 2)) # 'bbaa'", + "week": 4 + }, + { + "item_id": "kp-5", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "The 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation.", + "week": 4 + }, + { + "item_id": "kp-5-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Importing string constants\nimport string\nprint(string.ascii_lowercase) # 'abcdef...'\nprint(string.digits) # '0123456789'", + "week": 4 + }, + { + "item_id": "kp-6", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "strip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively.", + "week": 4 + }, + { + "item_id": "kp-6-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Stripping whitespace and characters\ns = ' abc '\nprint(s.strip()) # 'abc'\ns2 = 'eeabcdee'\nprint(s2.strip('e')) # 'abcd'", + "week": 4 + }, + { + "item_id": "kp-7", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Pattern to remember: `find` returns `-1`; `index` raises `ValueError` if the substring is missing.", + "week": 4 + }, + { + "item_id": "kp-manual-string-method-results", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "String methods like `replace`, `capitalize`, `split`, and `join` return new values; the original string stays unchanged unless you assign the result.", + "week": 4 + }, + { + "item_id": "kp-manual-string-method-results-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "replace() returns a new string\nnumber = '020-525-1400'\ncleaned = number.replace('-', '')\nprint(number) # '020-525-1400'\nprint(cleaned) # '0205251400'", + "week": 4 + }, + { + "item_id": "ai-example-1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Behavior when substring is missing\ns = 'abc'\nprint(s.find('z')) # -1\n# print(s.index('z')) # Raises ValueError\nBoth find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError.", + "week": 4 + }, + { + "item_id": "ai-example-2", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Slicing examples\ns = '01234567'\nprint(s[::4]) # '04'\nprint(s[::-2]) # '7531'\nSlicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string.", + "week": 4 + }, + { + "item_id": "ai-example-3", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Joining a list into a string\nwords = ['a', 'b', 'c']\nprint('-'.join(words)) # 'a-b-c'\nprint(''.join(words)) # 'abc'\nThe join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator.", + "week": 4 + }, + { + "item_id": "ai-example-4", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Limiting replacements\ns = 'aaaa'\nprint(s.replace('a', 'b', 2)) # 'bbaa'\nReplaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements.", + "week": 4 + }, + { + "item_id": "ai-example-5", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Importing string constants\nimport string\nprint(string.ascii_lowercase) # 'abcdef...'\nprint(string.digits) # '0123456789'\nThe 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation.", + "week": 4 + }, + { + "item_id": "ai-example-6", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Stripping whitespace and characters\ns = ' abc '\nprint(s.strip()) # 'abc'\ns2 = 'eeabcdee'\nprint(s2.strip('e')) # 'abcd'\nstrip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively.", + "week": 4 + }, + { + "item_id": "ai-example-7", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "s1 = 'abcdefghabcdefgh'\ns1 = 'abcdefghabcdefgh'\nprint(s1.find('i'))\nprint(s1[s1.find('i')])\nprint(s1.index('i'))", + "week": 4 + }, + { + "item_id": "ai-example-8", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "s1 = 'abcdefghabcdefgh'\ns1 = 'abcdefghabcdefgh'\nprint(s1.find('e'))\nprint(s1.index('e', 5))\nprint(s1.find('e', 5, 10))\nprint(s1.index('e', 5, 13))\nprint(s1.find('ef'))\nprint(s1.index('q'))", + "week": 4 + }, + { + "item_id": "manual-string-format-method", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Build strings with `.format(...)`\ntemplate = \"{} scored {} points\"\nprint(template.format(\"Ada\", 9))\nUse `.format(...)` on the template string, and remember it returns a new string instead of changing the original text in place.\nAda scored 9 points", + "week": 4 + }, + { + "item_id": "manual-string-islower-method", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Check lowercase letters with `.islower()`\nprint(\"amsterdam\".islower())\nprint(\"Amsterdam\".islower())\nprint(\"123\".islower())\n`.islower()` only returns `True` when the string contains at least one cased character and all cased characters are lowercase.\nTrue\nFalse\nFalse", + "week": 4 + }, + { + "item_id": "manual-string-repetition", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Repeat text with string multiplication\nprint(3 * \"ha\")\nprint(\"ab\" * 2)\nBoth `n * text` and `text * n` repeat the string `n` times, which is a common concise exam pattern.\nhahaha\nabab", + "week": 4 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes?\nA\nB\nC\nD\nA\nStrings in Python are immutable. The .replace() method returns a new string but does not modify the original. Option A returns the original string with dashes because the result of .replace() was not assigned back to the variable.", + "week": 4 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?\nA\nB\nC\nD\nB\nThe count() method is a string method, not a standalone function. It is called using the dot notation on a string object.", + "week": 4 + }, + { + "item_id": "ks-5198d93ec1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "String Searching: find vs index\nBoth find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError.\nBehavior when substring is missing\ns = 'abc'\nprint(s.find('z')) # -1\n# print(s.index('z')) # Raises ValueError", + "week": 4 + }, + { + "item_id": "ks-f80f1bf556", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "String Slicing with Step\nSlicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string.\nSlicing examples\ns = '01234567'\nprint(s[::4]) # '04'\nprint(s[::-2]) # '7531'", + "week": 4 + }, + { + "item_id": "ks-cdb152720e", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "The join Method\nThe join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator.\nJoining a list into a string\nwords = ['a', 'b', 'c']\nprint('-'.join(words)) # 'a-b-c'\nprint(''.join(words)) # 'abc'", + "week": 4 + }, + { + "item_id": "ks-45aead894c", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "The replace Method\nReplaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements.\nLimiting replacements\ns = 'aaaa'\nprint(s.replace('a', 'b', 2)) # 'bbaa'", + "week": 4 + }, + { + "item_id": "ks-bdea67862f", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "The string Module\nThe 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation.\nImporting string constants\nimport string\nprint(string.ascii_lowercase) # 'abcdef...'\nprint(string.digits) # '0123456789'", + "week": 4 + }, + { + "item_id": "ks-e4dc502d3e", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "String Stripping\nstrip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively.\nStripping whitespace and characters\ns = ' abc '\nprint(s.strip()) # 'abc'\ns2 = 'eeabcdee'\nprint(s2.strip('e')) # 'abcd'", + "week": 4 + }, + { + "item_id": "aiq-1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do you include literal curly braces {} in an f-string?\nIn f-strings, curly braces are escaped by doubling them ({{ and }}).\nF-strings", + "week": 4 + }, + { + "item_id": "kp-1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "F-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation.", + "week": 4 + }, + { + "item_id": "kp-1-d1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Simple f-string\nname = 'Jan'\nprint(f'{name} studies Python.') # 'Jan studies Python.'", + "week": 4 + }, + { + "item_id": "kp-2", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Using f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value.", + "week": 4 + }, + { + "item_id": "kp-2-d1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Debug shortcut\nval = 10\nprint(f'{val=}') # 'val=10'", + "week": 4 + }, + { + "item_id": "kp-3", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "You can specify formatting after a colon, such as padding numbers with zeros.", + "week": 4 + }, + { + "item_id": "kp-3-d1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Zero-padding an integer\nnum = 7\nprint(f'{num:03d}') # '007'", + "week": 4 + }, + { + "item_id": "kp-4", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Official assessments also use `.format(...)` placeholders. The same width and zero-padding ideas still apply there, for example `'{:04d}'.format(n)`.", + "week": 4 + }, + { + "item_id": "kp-4-d1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Padding with `.format(...)`\nscore = 91\nprint('Score: {:04d}'.format(score))", + "week": 4 + }, + { + "item_id": "ai-example-1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Simple f-string\nname = 'Jan'\nprint(f'{name} studies Python.') # 'Jan studies Python.'\nF-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation.", + "week": 4 + }, + { + "item_id": "ai-example-2", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Debug shortcut\nval = 10\nprint(f'{val=}') # 'val=10'\nUsing f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value.", + "week": 4 + }, + { + "item_id": "ai-example-3", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Zero-padding an integer\nnum = 7\nprint(f'{num:03d}') # '007'\nYou can specify formatting after a colon, such as padding numbers with zeros.", + "week": 4 + }, + { + "item_id": "ai-example-4", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Using `.format(...)` with placeholders\nname = 'Jan'\nscore = 7\nprint('Student {} scored {:03d}'.format(name, score))\nThe official resit material still uses `.format(...)`, so it is worth recognizing positional placeholders and width specs alongside f-strings.\nStudent Jan scored 007", + "week": 4 + }, + { + "item_id": "ks-72dda5450c", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "F-strings Basics\nF-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation.\nSimple f-string\nname = 'Jan'\nprint(f'{name} studies Python.') # 'Jan studies Python.'", + "week": 4 + }, + { + "item_id": "ks-ea5a4acb43", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "F-strings Debugging\nUsing f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value.\nDebug shortcut\nval = 10\nprint(f'{val=}') # 'val=10'", + "week": 4 + }, + { + "item_id": "ks-acb7f400b2", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "F-strings Formatting\nYou can specify formatting after a colon, such as padding numbers with zeros.\nZero-padding an integer\nnum = 7\nprint(f'{num:03d}') # '007'", + "week": 4 + }, + { + "item_id": "manual-self", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Why is `self` the first parameter of an instance method?\n`self` is the current object, so the method can read and update that object's attributes.\nclass Flight:\n def set_date(self, date):\n self.date = date", + "week": 4 + }, + { + "item_id": "manual-method-call", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Why does `obj.set_date(obj, x)` pass too many arguments?\nWhen you call a method on an object, Python passes the object as `self` automatically. Writing it again adds one argument too many.\nobj.set_date(x) # correct\nobj.set_date(obj, x) # too many args", + "week": 4 + }, + { + "item_id": "manual-init-default", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do default values in `__init__` make constructor arguments optional?\nA default like `vehicle_mode='land'` can be omitted when the object is created, but the instance still receives that attribute value.\nclass Vehicle:\n def __init__(self, name, vehicle_mode='land'):\n self.name = name\n self.vehicle_mode = vehicle_mode", + "week": 4 + }, + { + "item_id": "kp-1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A class defines methods and attribute layout; `__init__` runs when you create an object and stores instance data on `self`.", + "week": 4 + }, + { + "item_id": "kp-1-d1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Defining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color", + "week": 4 + }, + { + "item_id": "kp-2", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`self` refers to the current instance, so instance methods read and write data through `self.attr`.", + "week": 4 + }, + { + "item_id": "kp-2-d1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'", + "week": 4 + }, + { + "item_id": "kp-3", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`self.x` is per object; a class attribute is shared until an instance shadows it with its own value.", + "week": 4 + }, + { + "item_id": "kp-3-d1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Shared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1", + "week": 4 + }, + { + "item_id": "kp-4", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Method calls pass `self` automatically: `obj.set_date(x)` is correct; `obj.set_date(obj, x)` passes one argument too many.", + "week": 4 + }, + { + "item_id": "kp-manual-init-defaults", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Constructor defaults can make arguments optional, but mutable per-instance state should start from `None` and be created inside `__init__`.", + "week": 4 + }, + { + "item_id": "kp-manual-init-defaults-d1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Optional constructor argument\nclass Vehicle:\n def __init__(self, name, mode='land'):\n self.name = name\n self.mode = mode", + "week": 4 + }, + { + "item_id": "kp-manual-init-defaults-d2", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Fresh list per object\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores", + "week": 4 + }, + { + "item_id": "ai-example-1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Defining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color\nA class defines methods and attribute layout; `__init__` runs when you create an object and stores instance data on `self`.", + "week": 4 + }, + { + "item_id": "ai-example-2", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`.", + "week": 4 + }, + { + "item_id": "ai-example-3", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Shared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1\n`self.x` is per object; a class attribute is shared until an instance shadows it with its own value.", + "week": 4 + }, + { + "item_id": "ai-example-6", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Subclassing `str`\n#\nclass New_str(str):\n def index(self, needle, start = 0):\n return self.find(needle, start)\n\na = New_str(\"abcd\")\nprint(a.upper()) \nprint(a.find(\"d\")) \nprint(a.find(\"e\")) \nprint(a.index(\"d\")) \nprint(a.index(\"e\"))\nYou can subclass a built-in type to add custom methods while keeping the original string behavior.", + "week": 4 + }, + { + "item_id": "manual-oop-attrs", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Class attribute vs instance attribute\nclass Rectangle:\n units = 'cm'\n\n def __init__(self, width):\n self.width = width\n\nr1 = Rectangle(3)\nr2 = Rectangle(5)\nr2.units = 'm'\nprint(r1.units, r2.units)\n`self.width` is per object; `Class.units` is shared until an instance shadows it with its own attribute.\ncm m", + "week": 4 + }, + { + "item_id": "manual-oop-init-defaults", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state should start from `None` and be created inside `__init__`.", + "week": 4 + }, + { + "item_id": "manual-oop-constructor-defaults", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Constructor defaults belong in `__init__` parameters\nclass Vehicle:\n def __init__(self, name, mode=\"land\"):\n self.name = name\n self.mode = mode\n\ncar = Vehicle(\"Mazda\")\nprint(car.name, car.mode)\nDefault constructor arguments let an instance omit optional information while still giving `self` a predictable initial state.\nMazda land", + "week": 4 + }, + { + "item_id": "manual-oop-state-compare", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def better_than(self, other):\n return self.average() > other.average()\n\nbook_1 = Book(\"A\")\nbook_2 = Book(\"B\")\nfor score in [5, 3, 3]:\n book_1.add_review(score)\nfor score in [4, 4, 4]:\n book_2.add_review(score)\nprint(book_1.better_than(book_2))\nExam OOP reasoning often hinges on updating `self` in one method and then comparing derived state in a later method call.\nFalse", + "week": 4 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string \"land\". Which of the following code segments achieves what you want?\nA\nB\nC\nD\nA\nIn Python, default parameter values in the __init__ method allow for optional arguments during object creation. Option A correctly assigns the parameters to instance attributes.", + "week": 4 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book_1.show_rating())\nA\nB\nC\nD\nA\nThe average of scores [5, 3, 3] is 11 / 3 = 3.666... Using round(..., 1) results in 3.7.", + "week": 4 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the \"mode\" attribute should be equal to \"land\".\n\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\n\nWhich of the following code segments achieves what you want?\na\nb\nc\nd\na\nOption A correctly uses `self` as the first parameter of the `__init__` method, provides a default value for `vehicle_mode` (\"land\"), and properly assigns both arguments to instance attributes.", + "week": 4 + }, + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy?\na\nb\nc\nd\na\nIn Python, when calling a method on an object, the object itself is automatically passed as the first argument (self). Passing my_flight explicitly results in too many arguments being passed to set_date.", + "week": 4 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the following command print to the screen?\nprint(book_1.show_rating())\na\nb\nc\nd\na\nThe list of review scores is [5, 3, 3]. The sum is 11, and the length is 3. 11 / 3 is approximately 3.666... Using `round(..., 1)` rounds this float to one decimal place, resulting in 3.7.", + "week": 4 + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book.\n\nThe compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?\na\nb\nc\nd\nb\nOption A fails because its 'elif not avg_better:' condition triggers simply when the other book has an equal or better score, but it returns the other book's title without checking if the other book has at least as many reviews as the first book. Option B checks both pairs (self, other) and (other, self) against the requirements, returning the better one, or implicitly returning None if neither is better.", + "week": 4 + }, + { + "item_id": "ks-06b21ad349", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Class Definition and __init__\nA class is a blueprint. The __init__ method is the constructor called automatically when a new object is created to initialize attributes.\nDefining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color", + "week": 4 + }, + { + "item_id": "ks-9e278d1ee6", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "The self Parameter\nIn class methods, 'self' refers to the specific instance of the object. It must be the first parameter of any instance method.\nUsing self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'", + "week": 4 + }, + { + "item_id": "ks-5cbba26b09", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Class vs Instance Attributes\nInstance attributes (self.x) are unique to each object. Class attributes are defined outside methods and shared by all instances of the class.\nShared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1", + "week": 4 + }, + { + "item_id": "cs-0d319e4faf", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "class Rectangle:\nclass Rectangle:\n total_size = 0\n def __init__(self, length, width=1):\n self.length = length\n self.width = width\n Rectangle.total_size += self.length * self.width\n print(f'{self.length} by {self.width} created, {Rectangle.total_size = }')\n def size(self, data_type=int):\n return f\"The size = {data_type(self.length * self.width)}.\"\n def __del__(self):\n Rectangle.total_size -= self.length * self.width\n print(f'{self.length} by {self.width} deleted, {Rectangle.total_size = }')\n \nprint(Rectangle.total_size)\nrectangle_1 = Rectangle(2,3) \nrectangle_2 = Rectangle(2)\ndel rectangle_1 \ndel rectangle_2\n0\n2 by 3 created, Rectangle.total_size = 6\n2 by 1 created, Rectangle.total_size = 8\n2 by 3 deleted, Rectangle.total_size = 2\n2 by 1 deleted, Rectangle.total_size = 0", + "week": 4 + }, + { + "item_id": "cs-30e53467b8", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "class Rectangle:\nclass Rectangle:\n total_size = 0\n def __init__(self, length, width=1):\n self.length = length\n self.width = width\n Rectangle.total_size += self.length * self.width\n print(f'rectangle {self.length} by {self.width} created\\n{Rectangle.total_size = }')\n def size(self, data_type=int):\n return f\"The size = {data_type(self.length * self.width)}.\"\n def __del__(self):\n Rectangle.total_size -= self.length * self.width\n print(f'rectangle {self.length} by {self.width} deleted\\n{Rectangle.total_size = }')\n \nprint(Rectangle.total_size)\nrectangle_1 = Rectangle(2,3)\nrectangle_2 = Rectangle(3)\nrectangle_3 = Rectangle(2,2)\n\ndel rectangle_1\ndel rectangle_3\ndel rectangle_2\n0\nrectangle 2 by 3 created\nRectangle.total_size = 6\nrectangle 3 by 1 created\nRectangle.total_size = 9\nrectangle 2 by 2 created\nRectangle.total_size = 13\nrectangle 2 by 3 deleted\nRectangle.total_size = 7\nrectangle 2 by 2 deleted\nRectangle.total_size = 3\nrectangle 3 by 1 deleted\nRectangle.total_size = 0", + "week": 4 + }, + { + "item_id": "aiq-1", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "RuntimeError: dictionary changed size during iteration\nAdding or deleting dict entries while iterating over it causes RuntimeError", + "week": 4 + }, + { + "item_id": "kp-1", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "w4-error-handling-core", + "subtopic_title": "try/except and raise", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "The try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing.", + "week": 4 + }, + { + "item_id": "kp-1-d1", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Handling a ValueError\ns = 'abc'\ntry:\n idx = s.index('z')\nexcept ValueError:\n idx = -1", + "week": 4 + }, + { + "item_id": "kp-2", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "w4-error-handling-core", + "subtopic_title": "try/except and raise", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "You can use 'raise' to manually trigger an exception when a specific condition occurs.", + "week": 4 + }, + { + "item_id": "kp-2-d1", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Raising an error\ndef check_positive(n):\n if n < 0:\n raise ValueError('Number must be positive')\n return n", + "week": 4 + }, + { + "item_id": "kp-3", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "w4-error-handling-core", + "subtopic_title": "try/except and raise", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Catch the specific exception you expect when you know the failure mode. `except ValueError` documents the substring-missing case more clearly than a bare `except:`.", + "week": 4 + }, + { + "item_id": "kp-3-d1", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Specific exception handler\ns1 = 'abcdefghabcdefgh'\nneedle = 'i'\ntry:\n position = s1.index(needle)\nexcept ValueError:\n position = -1\nprint(position)", + "week": 4 + }, + { + "item_id": "ai-example-1", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "w4-error-handling-core", + "subtopic_title": "try/except and raise", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Handling a ValueError\ns = 'abc'\ntry:\n idx = s.index('z')\nexcept ValueError:\n idx = -1\nThe try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing.", + "week": 4 + }, + { + "item_id": "ai-example-2", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "w4-error-handling-core", + "subtopic_title": "try/except and raise", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Raising an error\ndef check_positive(n):\n if n < 0:\n raise ValueError('Number must be positive')\n return n\nYou can use 'raise' to manually trigger an exception when a specific condition occurs.", + "week": 4 + }, + { + "item_id": "ai-example-3", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "w4-error-handling-core", + "subtopic_title": "try/except and raise", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "def my_find(s,needle):\ndef my_find(s,needle):\n if (result := s.find(needle)) == -1:\n raise ValueError(\"substring not found\")\n return result\ns1 ='abcdefghabcdefgh'\nprint(my_find(s1, 'e'))\nprint(my_find(s1, 'i'))\nTrace the returned value, not just what gets printed while the function runs.", + "week": 4 + }, + { + "item_id": "ai-example-4", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "w4-error-handling-core", + "subtopic_title": "try/except and raise", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "def my_index(s,needle):\ndef my_index(s,needle):\n try:\n result = s.index(needle)\n except:\n result = -1\n return result\ns1 ='abcdefghabcdefgh'\nprint(my_index(s1, 'e'))\nprint(my_index(s1, 'i'))\nTrace the returned value, not just what gets printed while the function runs.", + "week": 4 + }, + { + "item_id": "ks-2c73fabc68", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Error Handling: try-except\nThe try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing.\nHandling a ValueError\ns = 'abc'\ntry:\n idx = s.index('z')\nexcept ValueError:\n idx = -1", + "week": 4 + }, + { + "item_id": "ks-40d373c410", + "card_id": "w4-error-handling", + "topic": "Error Handling", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "The raise Keyword\nYou can use 'raise' to manually trigger an exception when a specific condition occurs.\nRaising an error\ndef check_positive(n):\n if n < 0:\n raise ValueError('Number must be positive')\n return n", + "week": 4 + }, + { + "item_id": "manual-series-vs-dataframe", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What does `df['A']` return versus `df[['A']]`?\n`df['A']` returns a `Series`; `df[['A']]` returns a one-column `DataFrame`.\ndf['A']\ndf[['A']]", + "week": 5 + }, + { + "item_id": "manual-series-index", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What index does a `Series` get if you do not provide one explicitly?\nPandas uses the default integer index `0, 1, 2, ...`.\ns = pd.Series([10, 20, 30])", + "week": 5 + }, + { + "item_id": "manual-df-constructor", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How do you build a `DataFrame` from a dict of column names to lists?\nEach key becomes a column, and each list supplies that column's values row by row.\ndf = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})", + "week": 5 + }, + { + "item_id": "kp-manual-series-default-index", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A `Series` is 1D labeled data; if you do not supply an index, pandas uses `0, 1, 2, ...`.", + "week": 5 + }, + { + "item_id": "kp-manual-df-constructor", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A `DataFrame` is a 2D table; a dict of column names to equal-length lists is the standard constructor pattern.", + "week": 5 + }, + { + "item_id": "kp-manual-series-vs-df", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`df['A']` gives a `Series`, while `df[['A']]` gives a one-column `DataFrame`.", + "week": 5 + }, + { + "item_id": "manual-pandas-import", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "w5-pandas-core-structures-core", + "subtopic_title": "Series, DataFrame, and Creation Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Import pandas with the conventional alias\nimport pandas as pd\nUse the `pd` alias so constructors and methods stay short and readable during the exam.", + "week": 5 + }, + { + "item_id": "manual-pandas-series", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "w5-pandas-core-structures-core", + "subtopic_title": "Series, DataFrame, and Creation Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Create a `Series` from a list\ns = pd.Series([153, 160, 150], name='Length')\nprint(s)\nWithout an explicit index, pandas labels the rows `0, 1, 2, ...`.\n0 153\n1 160\n2 150\nName: Length, dtype: int64", + "week": 5 + }, + { + "item_id": "manual-pandas-df", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "w5-pandas-core-structures-core", + "subtopic_title": "Series, DataFrame, and Creation Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Build a `DataFrame` from a dict of columns\ndf = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})\nprint(df)\nEach dict key becomes a column and the lists provide the row values for that column.\n A B\n0 1 3\n1 2 4", + "week": 5 + }, + { + "item_id": "manual-pandas-select-shape", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "w5-pandas-core-structures-core", + "subtopic_title": "Series, DataFrame, and Creation Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`df['A']` versus `df[['A']]`\ndf['A'] # Series\ndf[['A']] # one-column DataFrame\nCheck the brackets carefully: one pair returns a `Series`, two pairs return a `DataFrame`.", + "week": 5 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is performed by adding series together. Using .loc[:, 'C'] correctly assigns the result to a new column for all rows.", + "week": 5 + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?\na\nb\nc\nd\na\nThe map() method on a Series expects a function, dictionary, or another Series. If passed a Series, it uses the values of the caller (s) to look up indices in the passed Series. This will lead to unexpected results (looking up float values like 2.0 as indices) instead of applying the mathematical transformation. The other options correctly perform the element-wise operation.", + "week": 5 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\na\nb\nc\nd\na\nPandas supports vectorized operations. You can add two Series (columns) together element-wise by directly using the `+` operator.", + "week": 5 + }, + { + "item_id": "ks-052ed25923", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "pd.Series\nA one-dimensional labeled array. If no index is provided, it defaults to integers starting from 0.\nCreating a Series from a list\nimport pandas as pd\ns1 = pd.Series([153, 160, 150], name='Length')", + "week": 5 + }, + { + "item_id": "ks-9a5d2c05fb", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "pd.DataFrame\nA two-dimensional tabular data structure. Most commonly created from a dictionary where keys are column names and values are lists.\nCreating from dictionary\nd = {'Name': ['A', 'B'], 'Weight': [55, 70]}\ndf = pd.DataFrame(d, index=['First', 'Second'])", + "week": 5 + }, + { + "item_id": "ks-75cf35c8b4", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "DatetimeIndex\nA specialized index for dates. Elements have attributes like .year, .month, and .day.\nFiltering by month\ndf.loc[[r for r in df.index if r.month == 4]]", + "week": 5 + }, + { + "item_id": "cs-82ef14b9d5", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 4\n1 6 5\n2 7 8", + "week": 5 + }, + { + "item_id": "cs-49cf15967e", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 3\n1 6 4\n2 7 7", + "week": 5 + }, + { + "item_id": "cs-c4c296595e", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.loc[1] += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 2 3\n1 6 5\n2 6 7", + "week": 5 + }, + { + "item_id": "cs-8bae99d6de", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A += [1, 2]\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7", + "week": 5 + }, + { + "item_id": "cs-cdfd529b3d", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A += [1, 2, 3]\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 3\n1 7 4\n2 9 7", + "week": 5 + }, + { + "item_id": "cs-2e178eda82", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.loc[[1,2]] += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 2 3\n1 6 5\n2 7 8", + "week": 5 + }, + { + "item_id": "cs-b3e0b57d7a", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A = df2.A.map(lambda x: 3 * x)\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 6 3\n1 15 4\n2 18 7", + "week": 5 + }, + { + "item_id": "cs-e6b6bd65f0", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.loc[1] = df2.loc[1].map(lambda x: 3 * x)\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 2 3\n1 15 12\n2 6 7", + "week": 5 + }, + { + "item_id": "cs-8ec741987c", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 += pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]})\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 7\n1 7 9\n2 9 13", + "week": 5 + }, + { + "item_id": "cs-b069af91f4", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "additional", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 += pd.DataFrame({'A':[2, 5, 6], 'B':[3, 4, 7]}, index=[4,5,6])\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 NaN NaN\n1 NaN NaN\n2 NaN NaN", + "week": 5 + }, + { + "item_id": "aiq-1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What happens if you run print(df.iloc[5, 2]) on a DataFrame with only 3 rows?\nUnlike slicing, accessing a specific single position with .iloc that is out of bounds raises an IndexError.\nSelection with iloc", + "week": 5 + }, + { + "item_id": "aiq-5", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line", + "week": 5 + }, + { + "item_id": "kp-1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics.", + "week": 5 + }, + { + "item_id": "kp-1-d1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Summary stats\nprint(df.describe())", + "week": 5 + }, + { + "item_id": "kp-1-d2", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nSelector | What it uses | Result\ndf.loc[row, col] | labels | endpoint-inclusive slicing\ndf.iloc[row, col] | positions | Python-style exclusive slice\ndf.head(n) | first rows | quick inspect\ndf[df['A'] > 0] | boolean filter | row subset", + "week": 5 + }, + { + "item_id": "kp-2", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Label-based selection. Slicing with .loc is inclusive of the end name.", + "week": 5 + }, + { + "item_id": "kp-2-d1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Select rows/cols by name\ndf.loc['First':'Third', ['Name', 'Weight']]", + "week": 5 + }, + { + "item_id": "kp-3", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Integer-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists).", + "week": 5 + }, + { + "item_id": "kp-3-d1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Select by position\ndf.iloc[0:2, 0:1] # Rows 0,1; Col 0", + "week": 5 + }, + { + "item_id": "kp-4", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Selecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame.", + "week": 5 + }, + { + "item_id": "kp-4-d1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Series vs DataFrame result\ntype(df.loc[2]) # Series\ntype(df.loc[[2]]) # DataFrame", + "week": 5 + }, + { + "item_id": "kp-5", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Filtering data by passing a mask of True/False values (often created via comparisons).", + "week": 5 + }, + { + "item_id": "kp-5-d1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Filter by condition\ndf[df['Weight'] > 60]\ndf.loc[df.Age < 155]", + "week": 5 + }, + { + "item_id": "kp-6", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Pattern to remember: df.loc[df.index % 2 == 0, [\"B\"]]", + "week": 5 + }, + { + "item_id": "ai-example-1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Summary stats\nprint(df.describe())\nUse .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics.", + "week": 5 + }, + { + "item_id": "ai-example-2", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Select rows/cols by name\ndf.loc['First':'Third', ['Name', 'Weight']]\nLabel-based selection. Slicing with .loc is inclusive of the end name.", + "week": 5 + }, + { + "item_id": "ai-example-3", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Select by position\ndf.iloc[0:2, 0:1] # Rows 0,1; Col 0\nInteger-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists).", + "week": 5 + }, + { + "item_id": "ai-example-4", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Series vs DataFrame result\ntype(df.loc[2]) # Series\ntype(df.loc[[2]]) # DataFrame\nSelecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame.", + "week": 5 + }, + { + "item_id": "ai-example-5", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Filter by condition\ndf[df['Weight'] > 60]\ndf.loc[df.Age < 155]\nFiltering data by passing a mask of True/False values (often created via comparisons).", + "week": 5 + }, + { + "item_id": "ai-example-6", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = [['A', 'B', 'C'],[153, 160, 150],[55, 70, 60]]\ndf1 = pd.DataFrame (d1)\ndf1 = df1.drop(1, axis = 0)\ndf1 = df1.drop(1, axis = 1)\nprint(df1)\nresult = df1.iloc[2, 2]\nprint(result)\nprint(type(result))\nDecide first whether the code is using labels (`.loc`) or integer positions (`.iloc`).\n0 2\n0 A C\n2 55 60", + "week": 5 + }, + { + "item_id": "ai-example-7", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {10:['A', 'B', 'C', 'D'], 13:[153, 160, 150, 190], 12:[55, 70, 60, 80], 17:[10, 11, 12, 13]}\ndf1 = pd.DataFrame (d1, index=[3, 2, 1, 0])\nprint(df1)\n\nprint(df1.loc[df1.loc[:,13] < 155])\nprint(df1.loc[[3,1]])\nprint(df1.iloc[::2])\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.", + "week": 5 + }, + { + "item_id": "ai-example-8", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "w5-inspecting-and-selecting-data-core", + "subtopic_title": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {10:['A', 'B', 'C', 'D'], 13:[153, 160, 150, 190], 12:[55, 70, 60, 80], 17:[10, 11, 12, 13]}\ndf1 = pd.DataFrame (d1, index=[3, 2, 1, 0])\nprint(df1)\n\n\nprint(df1.loc[[True, True, False, False], [False, True, False, True]])\nprint(df1.loc[[True]*2 + [False]*2, [False, True]*2])\nprint(df1.loc[[3,2], [13, 17]])\nprint(df1.iloc[:2, [1, -1]])\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.", + "week": 5 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list to return a DataFrame. Option D would return a Series.", + "week": 5 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that only contains those elements of column \"B\" in df that have an even-numbered index. Which of the following code lines will achieve what you want?\na\nb\nc\nd\na\nOption A uses boolean indexing (`df.index % 2 == 0`) to select rows with even index values, and specifically selects column \"B\" using `.loc`.", + "week": 5 + }, + { + "item_id": "ks-0114a2cff0", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Viewing Data\nUse .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics.\nSummary stats\nprint(df.describe())", + "week": 5 + }, + { + "item_id": "ks-57ff66f9f1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Selection: loc\nLabel-based selection. Slicing with .loc is inclusive of the end name.\nSelect rows/cols by name\ndf.loc['First':'Third', ['Name', 'Weight']]", + "week": 5 + }, + { + "item_id": "ks-dfc064979d", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Selection: iloc\nInteger-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists).\nSelect by position\ndf.iloc[0:2, 0:1] # Rows 0,1; Col 0", + "week": 5 + }, + { + "item_id": "ks-99fe849762", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Selection Result Types\nSelecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame.\nSeries vs DataFrame result\ntype(df.loc[2]) # Series\ntype(df.loc[[2]]) # DataFrame", + "week": 5 + }, + { + "item_id": "cs-3d987070d4", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = [['A', 'B', 'C'],[153, 160, 150],[55, 70, 60]]\ndf1 = pd.DataFrame (d1)\ndf1 = df1.drop(1, axis = 0)\ndf1 = df1.drop(1, axis = 1)\nprint(df1)\nresult = df1.iloc[2, 2]\nprint(result)\nprint(type(result))\n0 2\n0 A C\n2 55 60", + "week": 5 + }, + { + "item_id": "ks-f550a3ffc7", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Boolean Indexing\nFiltering data by passing a mask of True/False values (often created via comparisons).\nFilter by condition\ndf[df['Weight'] > 60]\ndf.loc[df.Age < 155]", + "week": 5 + }, + { + "item_id": "aiq-1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Given s = pd.Series(['abc', 'xAef']), what is the result of s.str.upper().str.count('A').mean()?\nUpper becomes ['ABC', 'XAEF']. 'A' appears once in each, so counts are [1, 1]. The mean of [1, 1] is 1.0.\nVectorized Operations", + "week": 5 + }, + { + "item_id": "aiq-2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors", + "week": 5 + }, + { + "item_id": "aiq-3", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: ", + "week": 5 + }, + { + "item_id": "aiq-4", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True", + "week": 5 + }, + { + "item_id": "kp-1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Sort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns.", + "week": 5 + }, + { + "item_id": "kp-1-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Sorting by column values\ndf.sort_values(by='Length', ascending=False)", + "week": 5 + }, + { + "item_id": "kp-2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Applying a scalar operation (like + or *) to an entire Series or DataFrame automatically.", + "week": 5 + }, + { + "item_id": "kp-2-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Scalar broadcasting\ndf['Height'] += 10 # Adds 10 to every cell in the column", + "week": 5 + }, + { + "item_id": "kp-3", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Accessible via .str, these allow string operations on every element of a Series.", + "week": 5 + }, + { + "item_id": "kp-3-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Chained string operations\ns.str.upper().str.count('A')", + "week": 5 + }, + { + "item_id": "kp-4", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A vectorized version of 'in' to check if elements are within a collection.", + "week": 5 + }, + { + "item_id": "kp-4-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Filtering with isin\nvowels = list('aeiou')\ns[s.str[-1].str.lower().isin(vowels)]", + "week": 5 + }, + { + "item_id": "kp-5", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Applies a function (often a lambda) to every element of a Series.", + "week": 5 + }, + { + "item_id": "kp-5-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Formatting with map\ndf['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g')", + "week": 5 + }, + { + "item_id": "kp-6", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Applies a function along an axis (0 for columns, 1 for rows) of a DataFrame.", + "week": 5 + }, + { + "item_id": "kp-6-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Row-wise average\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)", + "week": 5 + }, + { + "item_id": "kp-7", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Represented by np.nan. Use .isna() to detect and .fillna() to replace them.", + "week": 5 + }, + { + "item_id": "kp-7-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Handling NaNs\ndf.fillna('No value') # Replaces all NaNs", + "week": 5 + }, + { + "item_id": "kp-manual-drop-missing", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `.drop(...)` to remove labels and `.dropna()` to remove incomplete rows or columns; use `.fillna(...)` when you want to keep the shape and replace the missing values instead.", + "week": 5 + }, + { + "item_id": "kp-manual-drop-missing-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dropping a column by label\ndf = df.drop(1, axis=1)", + "week": 5 + }, + { + "item_id": "kp-manual-drop-missing-d2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Removing rows with missing values\ndf.dropna()", + "week": 5 + }, + { + "item_id": "ai-example-1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Sorting by column values\ndf.sort_values(by='Length', ascending=False)\nSort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns.", + "week": 5 + }, + { + "item_id": "ai-example-2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Scalar broadcasting\ndf['Height'] += 10 # Adds 10 to every cell in the column\nApplying a scalar operation (like + or *) to an entire Series or DataFrame automatically.", + "week": 5 + }, + { + "item_id": "ai-example-3", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Chained string operations\ns.str.upper().str.count('A')\nAccessible via .str, these allow string operations on every element of a Series.", + "week": 5 + }, + { + "item_id": "ai-example-4", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Filtering with isin\nvowels = list('aeiou')\ns[s.str[-1].str.lower().isin(vowels)]\nA vectorized version of 'in' to check if elements are within a collection.", + "week": 5 + }, + { + "item_id": "ai-example-5", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Formatting with map\ndf['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g')\nApplies a function (often a lambda) to every element of a Series.", + "week": 5 + }, + { + "item_id": "ai-example-6", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Row-wise average\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)\nApplies a function along an axis (0 for columns, 1 for rows) of a DataFrame.", + "week": 5 + }, + { + "item_id": "manual-working-values-string-vs-map", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`.str` methods vs `map(...)`\ns = pd.Series(['Aap', 'Nota', 'MIES'])\nprint(s.map(lambda x: x.lower()))\nprint(s.str.lower())\nUse `.str` for vectorized string operations; `map(...)` is useful when you need a custom per-value transformation.", + "week": 5 + }, + { + "item_id": "manual-working-values-axis-apply", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`apply(axis=0)` vs `apply(axis=1)`\ndf.loc['Av'] = df.apply(lambda x: x.mean(), axis=0)\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)\n`axis=0` works column by column; `axis=1` works row by row.", + "week": 5 + }, + { + "item_id": "ai-example-7", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Handling NaNs\ndf.fillna('No value') # Replaces all NaNs\nRepresented by np.nan. Use .isna() to detect and .fillna() to replace them.", + "week": 5 + }, + { + "item_id": "ai-example-8", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 = df2.applymap(lambda x: 3 * x)\nprint(df2)\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.", + "week": 5 + }, + { + "item_id": "manual-pandas-split-into-columns", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Split string data into multiple DataFrame columns\nimport pandas as pd\n\ndf = pd.DataFrame({\"place\": [\"Amsterdam; Noord-Holland\", \"Utrecht; Utrecht\"]})\ndf[[\"municipality\", \"province\"]] = df[\"place\"].str.split(\"; \", expand=True)\nprint(df)\nUse `.str.split(..., expand=True)` when the exam wants one text column unpacked into multiple DataFrame columns.\n place municipality province\n0 Amsterdam; Noord-Holland Amsterdam Noord-Holland\n1 Utrecht; Utrecht Utrecht Utrecht", + "week": 5 + }, + { + "item_id": "manual-pandas-map-column-sum", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Trace `map(lambda x: x + df['B'].sum())`\nimport pandas as pd\n\ndf = pd.DataFrame({\"A\": [1, 2], \"B\": [10, 20]})\nresult = df[\"A\"].map(lambda x: x + df[\"B\"].sum())\nprint(result.tolist())\n`df[\"B\"].sum()` is computed from the whole column, so each element from `A` gets the same total from `B` added to it.\n[31, 32]", + "week": 5 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which of the following code lines could NOT have created df2 from df1?\nA\nB\nC\nD\nA\nOption A would sort all 5 rows of df1 and keep columns A, C, D, resulting in a 5-row DataFrame. df2 only has 3 rows (indices 4, 3, 2).", + "week": 5 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like splitting a string and taking the first part) to every element in a pandas Series.", + "week": 5 + }, + { + "item_id": "ks-305a41a33e", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Sorting\nSort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns.\nSorting by column values\ndf.sort_values(by='Length', ascending=False)", + "week": 5 + }, + { + "item_id": "ks-f8eec928e1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Broadcasting\nApplying a scalar operation (like + or *) to an entire Series or DataFrame automatically.\nScalar broadcasting\ndf['Height'] += 10 # Adds 10 to every cell in the column", + "week": 5 + }, + { + "item_id": "ks-115ab52188", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Vectorized String Methods\nAccessible via .str, these allow string operations on every element of a Series.\nChained string operations\ns.str.upper().str.count('A')", + "week": 5 + }, + { + "item_id": "ks-2bed6c308f", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "isin()\nA vectorized version of 'in' to check if elements are within a collection.\nFiltering with isin\nvowels = list('aeiou')\ns[s.str[-1].str.lower().isin(vowels)]", + "week": 5 + }, + { + "item_id": "ks-17e621a20d", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "map()\nApplies a function (often a lambda) to every element of a Series.\nFormatting with map\ndf['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g')", + "week": 5 + }, + { + "item_id": "ks-0d2d15f8d2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "apply()\nApplies a function along an axis (0 for columns, 1 for rows) of a DataFrame.\nRow-wise average\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)", + "week": 5 + }, + { + "item_id": "ks-18a9645168", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Missing Data\nRepresented by np.nan. Use .isna() to detect and .fillna() to replace them.\nHandling NaNs\ndf.fillna('No value') # Replaces all NaNs", + "week": 5 + }, + { + "item_id": "aiq-1", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "During a .merge(how='left') operation, what is placed in a cell if no match is found in the right DataFrame?\nPandas uses NaN (Not a Number) to represent missing data resulting from non-overlapping joins.\nMerging", + "week": 5 + }, + { + "item_id": "kp-1", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Gluing DataFrames together using pd.concat().", + "week": 5 + }, + { + "item_id": "kp-1-d1", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Vertical stack\npd.concat([df1, df2], axis=0)", + "week": 5 + }, + { + "item_id": "kp-1-d2", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dense reference table\nOperation | Main axis/key idea | When useful\npd.concat([...], axis=0) | stack rows | same columns\npd.concat([...], axis=1) | add columns | aligned index\ndf.merge(...) | join on key(s) | relational combine\ndf.groupby(...) | split/apply/combine | aggregate by category", + "week": 5 + }, + { + "item_id": "kp-2", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Database-style joins using .merge(). 'how' determines the type (left, right, inner, outer).", + "week": 5 + }, + { + "item_id": "kp-2-d1", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Left join on a key\ndf1.merge(df2, on='Town', how='left')", + "week": 5 + }, + { + "item_id": "kp-3", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "The Split-Apply-Combine pattern using .groupby().", + "week": 5 + }, + { + "item_id": "kp-3-d1", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Grouped aggregation\ndf.groupby('Nationality')['Height'].median()", + "week": 5 + }, + { + "item_id": "ai-example-1", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Vertical stack\npd.concat([df1, df2], axis=0)\nGluing DataFrames together using pd.concat().", + "week": 5 + }, + { + "item_id": "ai-example-2", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Left join on a key\ndf1.merge(df2, on='Town', how='left')\nDatabase-style joins using .merge(). 'how' determines the type (left, right, inner, outer).", + "week": 5 + }, + { + "item_id": "ai-example-3", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Grouped aggregation\ndf.groupby('Nationality')['Height'].median()\nThe Split-Apply-Combine pattern using .groupby().", + "week": 5 + }, + { + "item_id": "ai-example-4", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noord Holland', 'Zuid Holland', 'Utrecht']})\n#print(dfprov)\n\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='left'))\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='right'))\n\ndfcombined = dftax.merge(dfprov, how='left')\ndfcombined.loc[:,'Province'] = dfcombined.loc[:,'Province'].fillna('Rest')\n# We replace the missing values with a string\n# As the groupby method ignores NaN values\nresult = dfcombined.groupby('Province')['Tax'].sum()\nresult = result.sort_values(ascending = False)\n# We want the highest paying Province first\n#print(result)\n\nprint(f\"Province {result.index[0]} has the highest tax revenue: {result[0]}\")\nprint(f\"Total tax: {result.sum()}\")\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.\nProvince Zuid Holland has the highest tax revenue: 60\nTotal tax: 100", + "week": 5 + }, + { + "item_id": "ai-example-5", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "w5-combining-data-core", + "subtopic_title": "Concatenation, Merging, and Grouping", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\nprint(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noord Holland', 'Zuid Holland', 'Utrecht']})\nprint(dfprov)\n\nprint(dftax.merge(dfprov, left_on='City', right_on = 'City', how='left'))\nprint(dftax.merge(dfprov, left_on='City', right_on = 'City', how='right'))\n\ndfcombined = dftax.merge(dfprov, how='left')\ndfcombined.loc[:,'Province'] = dfcombined.loc[:,'Province'].fillna('Rest')\n# We replace the missing values in the Province column with a string\n# As the groupby method ignores NaN values\nresult = dfcombined.groupby('Province')['Tax'].sum()\nresult = result.sort_values(ascending = False)\n# We want the highest paying Province first\nprint(result)\n\nprint(result[[0]])\nprint(result.sum())\nprint(result['Noord Holland'])\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.", + "week": 5 + }, + { + "item_id": "ks-591dd1aa33", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Concatenation\nGluing DataFrames together using pd.concat().\nVertical stack\npd.concat([df1, df2], axis=0)", + "week": 5 + }, + { + "item_id": "ks-21496ff1cd", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Merging\nDatabase-style joins using .merge(). 'how' determines the type (left, right, inner, outer).\nLeft join on a key\ndf1.merge(df2, on='Town', how='left')", + "week": 5 + }, + { + "item_id": "ks-f1be187b50", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Grouping\nThe Split-Apply-Combine pattern using .groupby().\nGrouped aggregation\ndf.groupby('Nationality')['Height'].median()", + "week": 5 + }, + { + "item_id": "cs-b46633d18d", + "card_id": "w5-combining-data", + "topic": "Combining Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noord Holland', 'Zuid Holland', 'Utrecht']})\n#print(dfprov)\n\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='left'))\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='right'))\n\ndfcombined = dftax.merge(dfprov, how='left')\ndfcombined.loc[:,'Province'] = dfcombined.loc[:,'Province'].fillna('Rest')\n# We replace the missing values with a string\n# As the groupby method ignores NaN values\nresult = dfcombined.groupby('Province')['Tax'].sum()\nresult = result.sort_values(ascending = False)\n# We want the highest paying Province first\n#print(result)\n\nprint(f\"Province {result.index[0]} has the highest tax revenue: {result[0]}\")\nprint(f\"Total tax: {result.sum()}\")\nProvince Zuid Holland has the highest tax revenue: 60\nTotal tax: 100", + "week": 5 + }, + { + "item_id": "aiq-1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Why does Python interpret {x * 2 for x in l1} as a set comprehension and not a dictionary comprehension?\nDictionary comprehensions require a 'key: value' syntax within the curly braces.\nComprehensions", + "week": 6 + }, + { + "item_id": "aiq-2", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions", + "week": 6 + }, + { + "item_id": "aiq-3", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy", + "week": 6 + }, + { + "item_id": "aiq-4", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function", + "week": 6 + }, + { + "item_id": "kp-1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Creates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order.", + "week": 6 + }, + { + "item_id": "kp-1-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Building a set of doubled odd numbers\ns1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}", + "week": 6 + }, + { + "item_id": "kp-2", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Since 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string.", + "week": 6 + }, + { + "item_id": "kp-2-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Double vowels in a string\ns2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python'])", + "week": 6 + }, + { + "item_id": "kp-3", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Allows creating complex nested structures like dictionaries within dictionaries in a single concise line.", + "week": 6 + }, + { + "item_id": "kp-3-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dictionary with sub-dictionaries\nresult = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}", + "week": 6 + }, + { + "item_id": "kp-4", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "The walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations.", + "week": 6 + }, + { + "item_id": "kp-4-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Using walrus to avoid double squaring\nl1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10]", + "week": 6 + }, + { + "item_id": "kp-5", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Comprehensions are generally preferred over combining map() and filter() with lambda functions for readability.", + "week": 6 + }, + { + "item_id": "kp-5-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Equivalent logic using map/filter\nl2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4])))", + "week": 6 + }, + { + "item_id": "kp-6", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Created using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory.", + "week": 6 + }, + { + "item_id": "kp-6-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Generator for large range\ngen = (x for x in range(1000000) if x % 3 == 0)", + "week": 6 + }, + { + "item_id": "kp-7", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Can include 'if' conditions to filter keys or values during dictionary creation.", + "week": 6 + }, + { + "item_id": "kp-7-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Filtering dictionary items\nd = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1}", + "week": 6 + }, + { + "item_id": "kp-8", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use enumerate() to access both the index and the value of items within a comprehension.", + "week": 6 + }, + { + "item_id": "kp-8-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Divide by index plus offset\nres = [val // (i + 6) for i, val in enumerate([46, 48])]", + "week": 6 + }, + { + "item_id": "ai-example-1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Building a set of doubled odd numbers\ns1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}\nCreates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order.", + "week": 6 + }, + { + "item_id": "ai-example-2", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Double vowels in a string\ns2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python'])\nSince 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string.", + "week": 6 + }, + { + "item_id": "ai-example-3", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Dictionary with sub-dictionaries\nresult = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}\nAllows creating complex nested structures like dictionaries within dictionaries in a single concise line.", + "week": 6 + }, + { + "item_id": "ai-example-4", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Using walrus to avoid double squaring\nl1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10]\nThe walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations.", + "week": 6 + }, + { + "item_id": "ai-example-5", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Equivalent logic using map/filter\nl2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4])))\nComprehensions are generally preferred over combining map() and filter() with lambda functions for readability.", + "week": 6 + }, + { + "item_id": "ai-example-6", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Generator for large range\ngen = (x for x in range(1000000) if x % 3 == 0)\nCreated using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory.", + "week": 6 + }, + { + "item_id": "ai-example-7", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Filtering dictionary items\nd = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1}\nCan include 'if' conditions to filter keys or values during dictionary creation.", + "week": 6 + }, + { + "item_id": "ai-example-8", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Divide by index plus offset\nres = [val // (i + 6) for i, val in enumerate([46, 48])]\nUse enumerate() to access both the index and the value of items within a comprehension.", + "week": 6 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this?\nA\nB\nC\nD\nC\nBoth options implement the conditional logic required to flip the case of each character in the list.", + "week": 6 + }, + { + "item_id": "ks-cacc4fbc21", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Set Comprehensions\nCreates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order.\nBuilding a set of doubled odd numbers\ns1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}", + "week": 6 + }, + { + "item_id": "ks-0e5c8b8b42", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "String Transformations via List Comprehension\nSince 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string.\nDouble vowels in a string\ns2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python'])", + "week": 6 + }, + { + "item_id": "ks-3e04c4d5e8", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Nested Dictionary Comprehensions\nAllows creating complex nested structures like dictionaries within dictionaries in a single concise line.\nDictionary with sub-dictionaries\nresult = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}", + "week": 6 + }, + { + "item_id": "ks-b9d93f2bc1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Walrus Operator in Comprehensions\nThe walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations.\nUsing walrus to avoid double squaring\nl1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10]", + "week": 6 + }, + { + "item_id": "ks-1bc815f6d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Map and Filter vs. Comprehensions\nComprehensions are generally preferred over combining map() and filter() with lambda functions for readability.\nEquivalent logic using map/filter\nl2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4])))", + "week": 6 + }, + { + "item_id": "ks-0a4fcae36d", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Generator Comprehensions\nCreated using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory.\nGenerator for large range\ngen = (x for x in range(1000000) if x % 3 == 0)", + "week": 6 + }, + { + "item_id": "ks-72c58bb6b2", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Dictionary Comprehensions with Logic\nCan include 'if' conditions to filter keys or values during dictionary creation.\nFiltering dictionary items\nd = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1}", + "week": 6 + }, + { + "item_id": "ks-dd2965ef50", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "Enumerate in Comprehensions\nUse enumerate() to access both the index and the value of items within a comprehension.\nDivide by index plus offset\nres = [val // (i + 6) for i, val in enumerate([46, 48])]", + "week": 6 + }, + { + "item_id": "aiq-1", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "What is the primary advantage of a generator over a list for large datasets?\nGenerators do not store the entire sequence in memory, which is essential for very large or infinite datasets.\nGenerators", + "week": 6 + }, + { + "item_id": "aiq-2", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: ", + "week": 6 + }, + { + "item_id": "kp-1", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Functions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls.", + "week": 6 + }, + { + "item_id": "kp-1-d1", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Simple step generator\ndef count(start, stop, step):\n while start <= stop:\n yield start\n start += step", + "week": 6 + }, + { + "item_id": "kp-2", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Objects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted.", + "week": 6 + }, + { + "item_id": "kp-2-d1", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Manual iteration\nit = iter([1, 2]); print(next(it)); print(next(it))", + "week": 6 + }, + { + "item_id": "ai-example-1", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Simple step generator\ndef count(start, stop, step):\n while start <= stop:\n yield start\n start += step\nFunctions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls.", + "week": 6 + }, + { + "item_id": "ai-example-2", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Manual iteration\nit = iter([1, 2]); print(next(it)); print(next(it))\nObjects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted.", + "week": 6 + }, + { + "item_id": "ai-example-3", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "myiterator = iter([1,3,5])\nmyiterator = iter([1,3,5])\n\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))", + "week": 6 + }, + { + "item_id": "ai-example-4", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "class Mylist(list):\nclass Mylist(list):\n pass\nmyiterator = iter(Mylist([1,3,5]))\n\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))", + "week": 6 + }, + { + "item_id": "ai-example-5", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "mygenerator = (x for x in range(100000000) if x%3 == 0 or x%4 == 0)\nmygenerator = (x for x in range(100000000) if x%3 == 0 or x%4 == 0)\nprint(next(mygenerator))\nprint(next(mygenerator))\nprint(next(mygenerator))\nprint(next(mygenerator))\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.", + "week": 6 + }, + { + "item_id": "ai-example-6", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "class Mylist(list):\nclass Mylist(list):\n def __iter__ (self):\n pass\nmyiterator = iter(Mylist([1,3,5]))\n\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))", + "week": 6 + }, + { + "item_id": "ai-example-7", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "def generatorfunction(start, stop, step):\ndef generatorfunction(start, stop, step):\n while (num:=start) <= stop:\n yield num\n start += step\n return 'End of numbers'\nfor x in generatorfunction(1, 5, 2):\n print(x)\nFor numeric variables, `a += 1` updates the stored value the same way as `a = a + 1`.", + "week": 6 + }, + { + "item_id": "ai-example-8", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "w6-generators-and-iterators-core", + "subtopic_title": "Iterator Protocol, Generator Functions, and Generator Comprehensions", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "def generatorfunction(start, stop, step):\ndef generatorfunction(start, stop, step):\n while True:\n num = start\n start += step\n if num <= stop:\n yield num\n else:\n return 'End of numbers'\nprint(list(generatorfunction(1, 5, 2)))\nFor numeric variables, `a += 1` updates the stored value the same way as `a = a + 1`.", + "week": 6 + }, + { + "item_id": "ks-900b394f8e", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Generator Functions\nFunctions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls.\nSimple step generator\ndef count(start, stop, step):\n while start <= stop:\n yield start\n start += step", + "week": 6 + }, + { + "item_id": "ks-cd030b9520", + "card_id": "w6-generators-and-iterators", + "topic": "Generators and Iterators", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Iterators\nObjects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted.\nManual iteration\nit = iter([1, 2]); print(next(it)); print(next(it))", + "week": 6 + }, + { + "item_id": "manual-strftime-vs-strptime", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "When do you use `strftime` versus `strptime`?\n`strftime` formats a datetime into text; `strptime` parses text into a datetime object.\ndt.strftime('%Y-%m-%d')\ndatetime.strptime('2024-05-20', '%Y-%m-%d')", + "week": 6 + }, + { + "item_id": "manual-timedelta-attrs", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "Which attributes exist directly on a `timedelta` object?\nA `timedelta` stores `days`, `seconds`, and `microseconds`; hours or weeks must be derived or supplied when constructing it.\ndelta = end - start\nprint(delta.days, delta.seconds)", + "week": 6 + }, + { + "item_id": "manual-day-of-year", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "selection_kind": "direct", + "search_text": "How can you compute the day number within the year from a datetime?\nSubtract January 1st of the same year, take `.days`, and add 1 so January 1st becomes day 1.\ndef day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "week": 6 + }, + { + "item_id": "kp-manual-datetime-now", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`datetime.now()` gives the current local datetime; use `.timestamp()` only when you specifically need seconds since the Unix epoch.", + "week": 6 + }, + { + "item_id": "kp-manual-datetime-format", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`strftime` formats a datetime into text; `strptime` parses text into a datetime object.", + "week": 6 + }, + { + "item_id": "kp-manual-datetime-delta", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Subtracting two datetimes gives a `timedelta`; its most-used direct attributes are `.days`, `.seconds`, and `.microseconds`.", + "week": 6 + }, + { + "item_id": "kp-manual-datetime-replace", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Datetime objects are immutable, so `.replace(...)` returns a new datetime instead of modifying the original one.", + "week": 6 + }, + { + "item_id": "kp-manual-datetime-iso", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `isoformat()` for an ISO-style timestamp, `isoweekday()` for Monday=1..Sunday=7, and `isocalendar()` when you need ISO year/week information.", + "week": 6 + }, + { + "item_id": "kp-manual-datetime-day-of-year", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "The day number within the year can be formatted with `%j` or computed with `(dt - datetime(dt.year, 1, 1)).days + 1`.", + "week": 6 + }, + { + "item_id": "manual-datetime-format", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Format a datetime with `strftime`\nfrom datetime import datetime\n\ndt = datetime(2024, 5, 20, 14, 30)\nprint(dt.strftime('%Y-%m-%d %H:%M'))\nUse `strftime` when the exam asks for a formatted string such as year-month-day or hour-minute.\n2024-05-20 14:30", + "week": 6 + }, + { + "item_id": "manual-datetime-parse", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Parse text with `strptime`\nfrom datetime import datetime\n\ndt = datetime.strptime('2024-05-20', '%Y-%m-%d')\nprint(dt)\nThe format string must match the input text exactly, including separators.\n2024-05-20 00:00:00", + "week": 6 + }, + { + "item_id": "manual-datetime-delta", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Subtract datetimes to get a `timedelta`\nfrom datetime import datetime\n\nstart = datetime(2024, 1, 1)\nend = datetime(2024, 1, 4)\nprint((end - start).days)\nDatetime subtraction gives a `timedelta`, whose `.days` attribute is often what exam questions want.\n3", + "week": 6 + }, + { + "item_id": "manual-datetime-replace", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "`.replace(...)` returns a new datetime\nfrom datetime import datetime\n\nd = datetime(2024, 5, 20)\nprint(d.replace(year=2026))\nprint(d)\nDatetime objects are immutable, so `.replace(...)` does not modify the original object in place.\n2026-05-20 00:00:00\n2024-05-20 00:00:00", + "week": 6 + }, + { + "item_id": "manual-datetime-iso", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "ISO and week-based helpers\nfrom datetime import datetime\n\nd = datetime(2024, 5, 20)\nprint(d.isoformat())\nprint(d.isoweekday())\nprint(d.isocalendar()[1])\nUse ISO helpers when the exam asks for an ISO string, the weekday with Monday as 1, or the ISO week number.", + "week": 6 + }, + { + "item_id": "manual-datetime-day-of-year", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Compute the day number within the year\nfrom datetime import datetime\n\ndef day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1\n\nprint(day_of_year(datetime(2024, 5, 20)))\nSubtract January 1st of the same year, then add 1 so January 1st becomes day 1.", + "week": 6 + }, + { + "item_id": "manual-datetime-overlap", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Check whether two datetime intervals overlap\nfrom datetime import datetime\n\nstart_a = datetime(2024, 5, 20, 9, 0)\nend_a = datetime(2024, 5, 20, 11, 0)\nstart_b = datetime(2024, 5, 20, 10, 30)\nend_b = datetime(2024, 5, 20, 12, 0)\n\noverlaps = max(start_a, start_b) < min(end_a, end_b)\nprint(overlaps)\nA reliable overlap check compares the later start with the earlier end; there is overlap only when the later start is still before the earlier end.\nTrue", + "week": 6 + }, + { + "item_id": "manual-datetime-strftime-loop", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Do datetime math before `strftime` turns values into strings\nfrom datetime import datetime, timedelta\n\nday = datetime(2024, 1, 1)\nlabels = []\nfor _ in range(3):\n labels.append(day.strftime(\"%Y-%m-%d\"))\n day += timedelta(days=1)\nprint(labels)\nAfter `strftime`, the value is plain text, so increment the datetime object first and only store formatted strings as the final display step.\n['2024-01-01', '2024-01-02', '2024-01-03']", + "week": 6 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?\nA\nB\nC\nD\nA\n1st string: contains '/' so it uses %m/%d/%Y -> month 3. 2nd: contains neither '-' nor '/' -> None. 3rd: contains '-' so it uses %d-%m-%Y -> month 2.", + "week": 6 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_exam", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 makes it 1-based (Jan 1st = day 1).", + "week": 6 + }, + { + "item_id": "ks-e643ee5e77", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "datetime.now and Timestamps\ndatetime.now() retrieves the current local time. timestamp() returns the seconds since the Unix Epoch (Jan 1, 1970).\nGetting current timestamp\nfrom datetime import datetime\nprint(datetime.now().timestamp())", + "week": 6 + }, + { + "item_id": "ks-755c23c4be", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "strftime: Date to String\nFormats a datetime object into a readable string using format codes (e.g., %Y for 4-digit year, %m for month).\nFormatting a date\nfrom datetime import datetime\nprint(datetime.now().strftime('%Y-%m-%d %H:%M'))", + "week": 6 + }, + { + "item_id": "ks-169cc25be1", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "strptime: String to Date\nParses a string into a datetime object based on a provided format template.\nParsing a date string\nfrom datetime import datetime\nd = datetime.strptime('2024-05-20', '%Y-%m-%d')", + "week": 6 + }, + { + "item_id": "ks-86cd7ede1c", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "Timedelta and Date Arithmetic\nTimedelta objects represent durations. Subtracting two datetimes creates a timedelta; adding a timedelta to a datetime shifts the date.\nCalculating days difference\nfrom datetime import datetime, timedelta\ndiff = datetime(2024, 1, 1) - datetime(2023, 1, 1)\nprint(diff.days)", + "week": 6 + }, + { + "item_id": "cs-905c77e1f3", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_notebook", + "bucket": "recommended", + "selection_kind": "source", + "search_text": "from datetime import datetime\nfrom datetime import datetime\nd = datetime.strptime(\"2024$05%20\",\"%Y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"2024*141\",\"%Y*%j\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"2024*20xyz1\",\"%Y*%Uxyz%w\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"202420Monday\",\"%Y%U%A\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"00:00:00 20-05-2024\", \"%H:%M:%S %d-%m-%Y\")\nprint(d)\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00", + "week": 6 + }, + { + "item_id": "ks-662456da41", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "source_lecture", + "bucket": "additional", + "selection_kind": "source", + "search_text": "The replace() Method\nDatetime objects are immutable. The replace() method creates a new datetime object with specific attributes changed.\nChanging the year of a date\nfrom datetime import datetime\nd = datetime.now().replace(year=2026)", + "week": 6 + } +] \ No newline at end of file diff --git a/data/vision_exam_pipeline/synthesis/round1.json b/data/vision_exam_pipeline/synthesis/round1.json new file mode 100644 index 0000000..164dd44 --- /dev/null +++ b/data/vision_exam_pipeline/synthesis/round1.json @@ -0,0 +1,3000 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:43Z", + "round": "round1", + "requires_human_review": true, + "input_evaluations_path": "data/vision_exam_pipeline/evaluations/round1.json", + "summary": { + "evaluation_count": 168, + "completed_evaluation_count": 168, + "suggestion_count": 151 + }, + "suggestions": [ + { + "suggestion_id": "round1:1", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: 'Comparing Objects with Multiple Criteria'. Snippet: 'When comparing two objects (A, B) based on multiple rules, remember that ! (A > B) does not imply (B > A). Example: def compare(self, other): if self.val > other.val and self.count >= other.count: return self; if other.val > self.val and other.count >= self.count: return other; return None'", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q02" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This directly addresses the logical pitfall in Option A and explains the necessity of the structure in Option B." + ], + "cons": [ + "Some students might infer the logic if they are strong in general boolean reasoning." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:10", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: count = sum([val == target for val in collection]). Show that this results in an integer, even if the count is zero.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q10" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This is the core 'trick' of the exam question. Without seeing that sum handles booleans, a student might incorrectly choose options B or D." + ], + "cons": [ + "The student might infer it if they see 'grade_counts' examples that work, but it's a leap for a 'zero knowledge' persona." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:100", + "kind": "edit_existing", + "target_item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "proposal": "Ensure the 'search_text' includes the full code for options a and b and clarifies why both work, matching the provided question explanation.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q09" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "The current snippet cut-off mentions an indentation error for Option A, which contradicts the 'Correct: C' (both work) answer in the exam question. Aligning these prevents student confusion." + ], + "cons": [ + "The student can likely infer the logic from the code patterns even if the explanation is cut off." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:101", + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Boolean String Methods. Methods like .islower(), .isupper(), and .isdigit() return True only if the string contains at least one character and all characters meet the criteria. Importantly, .islower() returns False for spaces, punctuation, and numbers as they are not lowercase letters.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q10" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "It provides the missing definition needed to definitively choose option (a) over (b) or (c) by clarifying that symbols and spaces are excluded." + ], + "cons": [ + "A student might intuitively guess that 'islower' only applies to letters, but 'zero prior knowledge' requires explicit confirmation." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:102", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a common question snippet: 'How do zip() and floor division (//) work?'. Content: `zip(list1, list2)` pairs elements by index: (list1[0], list2[0]), (list1[1], list2[1]). `//` is floor division, which divides and rounds down to the whole number (e.g., 5 // 2 = 2).", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q11" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "Directly addresses the two primary 'black boxes' in the question for a non-Python user." + ], + "cons": [ + "Basic math might be assumed, but zip is definitely a specific Python syntax that needs explanation." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:103", + "kind": "edit_existing", + "target_item_id": "exam-extra_practice-6-w1-sequences-and-access", + "proposal": "Expand the search text/explanation to explicitly define why option A ([::-2][::-1]) results in [2, 4, 6, 8, 10] (it reverses the reversed slice).", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q12" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "The current snippet text is truncated and might confuse students if the option letters (a, b, c, d) are shuffled in the exam." + ], + "cons": [ + "The logic 'starts at -1, step -2' is already present and might be enough for a smart student to eliminate options." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:104", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Common String Operations' showing: 1. text.replace('a', 'b', 1) to replace only the first occurrence; 2. index-based slicing like text[:5] and text[10:]; 3. concatenating slices with +.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q13" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This would allow a student to verify both Option A (slicing) and Option B (replace with count) without prior knowledge." + ], + "cons": [ + "The question hints at find(), but find() alone isn't enough to understand the replacement logic in the options." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:105", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining f-strings: f'Hello {name}' replaces {name} with the variable value.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q14" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "Essential to understand how both Option A and Option B work." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:106", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining list indexing: fruits[0] is the first item, fruits[1] is the second.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q14" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "Necessary to decode what Option B is actually doing." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:107", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining ', '.join(list): Result is 'item1, item2, item3' with no 'and'.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q14" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "Allows the student to realize Option A is a distractor that produces a different string than requested." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:108", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'df = pd.DataFrame({\"part1\": [x.split(\"-\")[0] for x in args], \"part2\": [x.split(\"-\")[1] for x in args]})'", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q15" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This pattern perfectly matches the logic required in the question (Option A), showing how to map processed strings into DataFrame columns." + ], + "cons": [ + "Students might be able to piece this together if they understand Dictionaries and Series separately, but a combined example is much clearer for beginners." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:109", + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "proposal": "Update the search_text to show a snippet of the code for the Vehicle class, specifically including a default value for the 'mode' attribute (e.g., mode='land').", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q16" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "It would show the exact pattern used in the question (OOP + Default Arg) in a single visual context." + ], + "cons": [ + "The logic can currently be synthesized by looking at two different snippets." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:11", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Topic Detail' or 'Cheat Sheet' item for Week 8 (Datetime) covering: 1. datetime(year, month, day, hour, minute) 2. timedelta(minutes=N) 3. Comparing datetimes using <, >, ==.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q12" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This would give the student the specific syntax needed to evaluate Options A and D, and recognize that Option B/C are invalid comparisons." + ], + "cons": [ + "Only unnecessary if the student is expected to infer library usage from the provided 'code_context' in the question, but 'zero knowledge' implies they need a reference." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:110", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String to Datetime Parsing (strptime)\nContent: datetime.strptime(string, format) converts text to a date object. \nFormat codes: %Y (4-digit year), %m (month 01-12), %d (day 01-31), %H (hour), %M (minute).\nExample: datetime.strptime('2023/1/10', '%Y/%m/%d') creates a date for Jan 10, 2023.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q17" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "It removes the small inferential leap required to understand that strptime is creating a date for January 10th based on the provided format string." + ], + "cons": [ + "Most students will guess the meaning of '%Y/%m/%d' correctly given the sample string '2023/1/10'." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:111", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Pandas Indexing Rules' snippet showing: 1. df['ColName'] (Valid), 2. df[['C1', 'C2']] (Valid), 3. df.loc[index, 'Col'] (Valid), 4. df[index, 'Col'] (Error).", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q18" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "It directly maps to the four options in the question, allowing a student to identify the error through pattern matching." + ], + "cons": [ + "If a student already knows dictionary-like indexing, they might guess D is wrong, but .loc (A/B) would still be confusing." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:112", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Conditional Expressions vs Statements' showing: 'return \"Yes\" if check else \"No\"' is equivalent to 'if check: return \"Yes\" else: return \"No\"'.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q19" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "Directly enables a student to recognize that both option (a) and (b) in the question are functionally identical." + ], + "cons": [ + "A student might guess if they understand standard 'if' blocks, but they won't be certain." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:113", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining 'self' as a reference to the current instance, used to access attributes defined in __init__.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q19" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "Ensures the student understands that 'self.legs' refers to the value passed during 'cat = Animals(..., legs=True)'." + ], + "cons": [ + "The existing 'Vehicle' class snippet hints at this, but doesn't explain the lookup mechanism within a method." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:114", + "kind": "edit_existing", + "target_item_id": "manual-oop-state-compare", + "proposal": "Add a compare method: def is_better(self, other): return self.average() > other.average()", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q20" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This would show the necessity of using brackets () when calling a method on both self and another object, directly addressing the 'd' answer rationale." + ], + "cons": [ + "The existing snippet already helps eliminate A and B based on the self parameter and list mutation syntax." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:115", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card for 'Datetime and Timedelta Arithmetic'. Explicitly state: 'datetime.strptime()' returns an object you can do math with. 'obj.strftime()' returns a STRING for display. You CANNOT add a timedelta to a string. Example: (date_obj + timedelta) works, but (date_string + timedelta) fails.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q21" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This directly explains the 'b' distractor in the question, which is the correct answer." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:116", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Datetime Formatting' that shows: from datetime import datetime; dt = datetime(2023, 5, 1); print(dt.strftime('%d-%m-%Y'))", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q22" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This provides the missing link for the student to understand the constructor order and the formatting codes required to pick Option A over C or B." + ], + "cons": [ + "Only if the student is expected to already know the datetime library, but the prompt specifies 'zero prior knowledge'." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:117", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Pandas Boolean Filtering' showing: df_filtered = df[df['Salary'] > 50000].", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q23" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This directly enables the student to understand the syntax for Operation 3." + ], + "cons": [ + "Snippet exam-intro_python_sample_final_24_25-6 mentions boolean masks, but the code snippet in the preview is cut off." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:118", + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "proposal": "Ensure the example code includes a lambda with a condition, e.g., s.map(lambda x: 'High' if x > 10 else 'Low').", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q23" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "It validates the syntax used in Option B of the question." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:119", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a key point (e.g., kp-pandas-lambda-agg) that shows: 'df['C'] = df['A'].map(lambda x: x + constant)' and explains that 'lambda x' represents each value in column 'A'.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q24" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This bridge is necessary to understand how the lambda variable 'x' interacts with the result of 'df['B'].sum()'." + ], + "cons": [ + "If the student already understands functions and basic aggregation, the existing .map() snippet might be enough to guess." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:12", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining Python's negative indexing (e.g., index -1 is the last item, -2 is second to last) and nested indexing (e.g., x[0][1] accesses the second element of the first item).", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q13" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "It would move the student from 'pattern matching' against old exams to actually understanding the logic required to solve the indexing math independently." + ], + "cons": [ + "The existing exam snippets are so similar that the student will likely find the answer by visual comparison alone." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:120", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Instance Attributes and 'self'. Content: 'To make an attribute available on an object (like my_car.name), you must assign it to self inside the __init__ method (e.g., self.name = vehicle_name). Without self, the variable only exists temporarily during creation.'", + "source_question_ids": [ + "sample-final-plus-answers-q01" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "Provides a clear reason to choose Option A over Option D, as Option D defines variables without self." + ], + "cons": [ + "Option A is already the most likely choice for a student matching the default value syntax provided in 'manual-init-default'." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:121", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Common Math Built-ins for Lists. Content: Use `sum(list)` to add all numbers, `len(list)` to count items, and `round(number, 1)` to round to one decimal place. Example: `round(10/3, 1)` returns `3.3`.", + "source_question_ids": [ + "sample-final-plus-answers-q02" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "The question relies on a calculation involving all three of these functions. Without knowing what 'round(..., 1)' does, a student might guess 4 (b) or 3.67 (d)." + ], + "cons": [ + "Students might infer sum/len from context, but 'round(..., 1)' is more specific." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:122", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Printing List of Dictionaries with Formatting. Content: To iterate through a list of dicts: `for item in my_list: print(f\"{item['key']}\")`. To format decimals to 1 place: `{value:.1f}`.", + "source_question_ids": [ + "sample-final-plus-answers-q03" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "The exam question specifically mentions one decimal place, but Option A in the JSON actually omits the format specifier. Providing the specific syntax ensures the student can handle variations where precision is required." + ], + "cons": [ + "The 'source_exam' snippets likely already contain the full solution in the actual rendered card." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:123", + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "proposal": "Add the text of the DataFrame 'df' (rows 1-6) to this snippet so it is fully self-contained without needing to look at 'exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data'.", + "source_question_ids": [ + "sample-final-plus-answers-q05" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It ensures the student has both the data context and the solution logic in a single view, which is critical for zero-knowledge students." + ], + "cons": [ + "The student can select multiple snippets, but a single consolidated card is more efficient for a cheat sheet." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:124", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Formatting Cheat Sheet' snippet listing %d (day), %m (month), %Y (year), and %H:%M (time).", + "source_question_ids": [ + "sample-final-plus-answers-q07" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It empowers the student to decode any strptime format string rather than just recognizing this specific exam solution." + ], + "cons": [ + "The database already contains many specific exam questions covering these codes individually." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:125", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Cheat Sheet' snippet: '%d: Day (01-31), %m: Month (01-12), %Y: Year (4-digit). datetime.strptime(str, format) parses strings; object.month extracts the month integer.'", + "source_question_ids": [ + "sample-final-plus-answers-q09" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It would allow students to solve any datetime parsing question rather than relying on finding a verbatim copy of the exam question." + ], + "cons": [ + "The verbatim snippet already exists in this specific dataset." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:126", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Comprehension Syntax' summary card: 1. Dictionary: {key: value for item in iterable}, 2. List: [value for item in iterable], 3. Set: {value for item in iterable}.", + "source_question_ids": [ + "sample-final-plus-answers-q11" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It allows the student to answer any variation of this question (e.g., 'create a set' or 'create a list') rather than just memorizing this specific instance." + ], + "cons": [ + "The existing snippets already label the types, which might be enough for a single-question exam." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:127", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet defining string case methods (.upper(), .lower(), .islower()) and the syntax for 'if-else' logic inside a list comprehension.", + "source_question_ids": [ + "sample-final-plus-answers-q12" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "Essential for a zero-knowledge student to evaluate why 'islower()' is the correct check vs the 'in alphabet' check used in Option B." + ], + "cons": [ + "Snippet 12 provides a shortcut, but it's risky due to conflicting rationales between exams." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:128", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Sequence Properties' card showing that len([]) == 0, len({}) == 0, and len('') == 0, and explaining that a == b == c is only True if all three are identical.", + "source_question_ids": [ + "sample-final-plus-answers-q17" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It bridges the gap for absolute beginners who might not know {} is a dictionary or that comparisons can be chained in Python." + ], + "cons": [ + "The existing 'intro_python_sample_final' snippet already hints at this logic." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:129", + "kind": "add_new", + "target_item_id": "", + "proposal": "List Comprehension: [expression for item in iterable] creates a new list by running the expression for every item. Example: [i*2 for i in range(3)] generates [0, 2, 4].", + "source_question_ids": [ + "sample-final-plus-answers-q18" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It helps students understand that the brackets in the answer aren't just for a list, but are a loop that generates sublists." + ], + "cons": [ + "The student might infer the behavior from the direct-match snippet provided in the exam-intro snippet." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:13", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining the range() function: range(0, 10) produces numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The number 10 is not included.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q14" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This directly addresses the confusion between range(0, 20) and range(0, 21) which is the primary distractor in options A and C." + ], + "cons": [ + "Students might infer it from the 'while i < 11' explanation, but it is a risky assumption for a total beginner." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:130", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining 'Sorted Dictionary Iteration': 'To process a dictionary in order of its keys, use `for key in sorted(my_dict.keys()):`. This ensures you visit keys from smallest to largest, which is useful for calculating running totals.'", + "source_question_ids": [ + "sample-final-plus-answers-q19" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It directly explains the logic behind Option B, which is often the more confusing part of this specific question for beginners." + ], + "cons": [ + "The 'best' snippet already tells the student that both options work, which might be enough for a 'cheat sheet' context." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:131", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'zip(l1, l2) creates pairs of elements from two lists at the same index. enumerate(l, start) creates pairs of (index, element), where the index starts at the specified value (default 0).'", + "source_question_ids": [ + "sample-final-plus-answers-q20" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It allows a student to derive the answer logically if the lists or indices were modified, rather than relying on a memorized exam answer." + ], + "cons": [ + "The direct exam match already provides the answer for this specific question." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:132", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet detailing that Python string methods like .count(), .find(), and .index() are case-sensitive by default (e.g., 'A' != 'a').", + "source_question_ids": [ + "sample-final-plus-answers-q22" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It ensures the student understands why the answer is 1 and not 2, reinforcing the logic behind the specific example provided in the question." + ], + "cons": [ + "The syntax rule (dot notation vs function call) is the primary hurdle for the question, which is already covered." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:133", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Lambda Basics' that explains: 'lambda x: x + 5' means 'take x and add 5 to it'.", + "source_question_ids": [ + "sample-final-plus-answers-q23" + ], + "source_exams": [ + "sample-final-plus-answers" + ], + "pros": [ + "It allows the student to perform the calculation themselves rather than just relying on matching the search text of a previous exam question." + ], + "cons": [ + "The existing sample final snippet already performs the calculation for the student." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:134", + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: OOP Fundamentals. Content: In Python, `__init__` is used to set attributes on a new object. Use `self.attribute_name = value`. Always include `self` as the first parameter. Example: `class MyClass: def __init__(self, val): self.val = val`", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q01" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "This helps the student eliminate Option D (missing self) and Option C (incorrectly using return instead of self assignment)." + ], + "cons": [ + "Option A is the only one showing both the correct default value syntax AND self-assignment, so the existing snippets might be enough to guess correctly." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:135", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point: 'The round(value, n) function rounds a number to n decimal places. Example: round(3.6666, 1) results in 3.7.'", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q02" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "The question requires choosing between 3.7 and 3.67; knowing how the '1' in round(..., 1) works is the final step to the correct answer." + ], + "cons": [ + "The term 'round' is intuitive enough for many students to guess the behavior correctly given the options." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:136", + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: F-String Float Formatting. Syntax: f'{value:.1f}' rounds to 1 decimal place. Example: price = 5.0; print(f'{price:.2f}') outputs 5.00.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q03" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "This provides the underlying logic for rounding, which is a core part of the question's 'distractor' logic (ensuring the student knows how to get 7.5 instead of 7.500000)." + ], + "cons": [ + "Since the exact question is already in the database, the student might just copy the answer without needing the rule." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:137", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a conceptual snippet explaining 'Pandas Column Arithmetic' that shows how df['C'] = df['A'] + df['B'] performs a row-by-row sum and stores it in 'C'.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q05" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "It helps the student understand the 'why' and apply the knowledge to variations (e.g., subtraction or multiplication) rather than just memorizing one specific question." + ], + "cons": [ + "The student can already answer this exact question because it is duplicated in the exam snippets." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:138", + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "proposal": "Update the 'topic' from 'string-operations-and-methods' to 'Inspecting and Selecting Data' or 'Pandas Indexing'.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q06" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "The current tag is misleading as the content is about Pandas DataFrame selection, not string manipulation." + ], + "cons": [ + "The search_text is already accurate and will be found by the RAG system regardless of the label." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:139", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a foundational snippet explaining that .loc[2:4] includes labels 2, 3, and 4, whereas .iloc[[3, 2, 1]] selects the 4th, 3rd, and 2nd rows respectively.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q07" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "This allows the student to understand why the other options (B, C, D) *could* have created df2, rather than just knowing why A could not." + ], + "cons": [ + "The direct explanation for Option A in the existing snippet is already sufficient to select the right answer." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:14", + "kind": "edit_existing", + "target_item_id": "ks-2a6510492d", + "proposal": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). This applies to all functions, including those nested inside others. Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates).", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q15" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "It explicitly bridges the gap between simple local variables and variables defined in nested function structures, which is the core of this specific exam question." + ], + "cons": [ + "The current definition 'defined inside a function' already technically covers nested functions, and the exam options don't require distinguishing between 'local' and 'non-local'." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:140", + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "proposal": "Expand the snippet text to include the full logic: 'The .map(lambda x: x.split(\"; \")[0]) method allows applying the split function to each element and taking the first part.'", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q08" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "The current text cuts off at '(like spli'. Showing the full code ensures a student can confidently identify Option A without guessing 'lambda' syntax." + ], + "cons": [ + "The current text is already highly suggestive of the correct answer." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:141", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a reference snippet for Datetime format strings: %Y (4-digit year), %y (2-digit year), %m (month), %d (day), %H (hour), %M (minute), %S (second).", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q09" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "This would allow a student to solve any datetime parsing question, even if the specific question isn't in the database." + ], + "cons": [ + "The specific exam question snippet already provides the necessary interpretation for this particular task." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:142", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining that 'datetime(year, month, day)' requires day to be at least 1, and that you cannot directly add an integer to a timedelta object (you must add another timedelta or convert to int first).", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q10" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "It would allow a student to systematically eliminate options B, C, and D rather than just identifying A as plausible." + ], + "cons": [ + "The current 'best snippet' is so similar to the correct answer that most students will pick A regardless." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:143", + "kind": "add_new", + "target_item_id": "", + "proposal": "A syntax reference card for list comprehensions showing: 1. [f(x) for x in list if cond] (filtering) vs 2. [f(x) if cond else g(x) for x in list] (transformation).", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q12" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "The question's main challenge is the syntax placement of the 'if-else' (Option A vs B). A direct syntax guide would make the choice trivial for a non-Python user by showing that 'if-else' must come before the 'for' keyword." + ], + "cons": [ + "The existing exam snippet already points to 'conditional logic' which might be enough for an intuitive student to pick the only syntactically plausible option (A)." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:144", + "kind": "add_new", + "target_item_id": "", + "proposal": "Conceptual Card: 'Comparison Rules by Type'. Rule 1: Integers and Floats are equal if they represent the same number (e.g., 3 == 3.0 is True). Rule 2: Strings are never equal to numbers (e.g., '3' == 3 is False). Rule 3: Chained comparisons (a == b == c) are treated as (a == b) AND (b == c).", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q13" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "It abstracts the logic from the exam snippets into a clear set of rules that a student can apply to any similar question." + ], + "cons": [ + "The explanation in the sample final exam snippet already provides this information, though in a question-specific context." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:145", + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "proposal": "Correct the snippet text to point to Option A and add a brief trace: 'In iteration 1: i=1, prev=0. After print, prev becomes 1. In iteration 2: i=2, prev=1...'", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q14" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "Prevents confusion caused by the current typo and reinforces the 'state-tracking' mechanic." + ], + "cons": [ + "The student might infer the logic from the code options regardless of the snippet's letter label." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:146", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'my_list = [True, False]; len([]); my_list[0] # Returns True'.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q17" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "This covers two minor gaps: that an empty list has length 0, and that [0] is used to retrieve the first item." + ], + "cons": [ + "A student might guess that 'empty' means 0 length and that indices start at 0 based on general logic." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:147", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Core Concept' snippet for List Comprehensions: Syntax: [expression for item in iterable]. This creates a new list by applying 'expression' to each 'item' in the sequence (like range). Example: [x*2 for x in [1,2,3]] results in [2,4,6].", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q18" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "It bridges the gap for students who see the range/slicing logic explained but don't recognize the structural 'wrapper' of the list comprehension." + ], + "cons": [ + "The direct explanation in the exam snippet might be enough for a student to simply pick the matching option without fully 'understanding' the loop." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:148", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'for key in sorted(prices.keys()): ...' and another showing 'sub_total = sum([val for key, val in d.items() if key < 10])'.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q19" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "This directly maps to the syntax used in Options A and B, allowing a student to recognize the patterns." + ], + "cons": [ + "If the goal is only to teach dictionary creation, existing snippets are okay, but for this specific logic question, they are inadequate." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:149", + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Iteration Helpers. Snippet: 'zip(l1, l2)' pairs elements by position: (l1[0], l2[0]), (l1[1], l2[1]). 'enumerate(l, start=0)' pairs index with value: (start, l[0]), (start+1, l[1]). These pairs are often used to populate dictionaries with d[key] = value.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q20" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "It allows a student to derive the result for any list content rather than just matching a specific example." + ], + "cons": [ + "The verbatim match in the existing exam snippets already solves this specific question perfectly." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:15", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Idioms' snippet: 'To pair adjacent elements in a list `L`, use `zip(L[:-1], L[1:])`. This creates pairs of (current, next). Alternatively, an indexed loop would use `range(len(L)-1)` to avoid an index-out-of-bounds error when accessing `L[i+1]`.'", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q16" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "It directly explains the syntax used in the correct answer (Option B) and clarifies the boundary conditions that make Option A incorrect." + ], + "cons": [ + "If the course focuses more on manual indexing than built-in idioms, but given it appears on the exam, it is necessary." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:150", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a knowledge snippet: 'Built-in functions and Dictionaries: Functions like sum(), min(), and max() can be applied directly to dictionary views. Example: result = sum(my_dict.values()) correctly totals all values.'", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q21" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "This would explicitly cover option (d) in the question, ensuring a student doesn't have to guess if sum() works on .values()." + ], + "cons": [ + "Option (a) is so clearly identified as an error by the best snippet that the student can identify it by elimination anyway." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:151", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Lambda and Operators' that explains: 1. lambda x: [expression] creates a small function. 2. ** is the power operator (e.g., 2**3 is 8). 3. *args allows passing any number of values as a list.", + "source_question_ids": [ + "trial-final-exam-solutions-introduction-to-python-3077951-q23" + ], + "source_exams": [ + "trial-final-exam-solutions-introduction-to-python-3077951" + ], + "pros": [ + "It bridges the gap from 'pattern matching the answer' to 'understanding the code' for a true zero-knowledge student." + ], + "cons": [ + "The student can already find the answer by matching the '30' and the numbers in the intro_python_sample_final snippet." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:16", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'In Python, two dictionaries are considered equal (==) if they contain the same set of key-value pairs. The order in which the pairs were added does not affect equality. Example: {1: 'a', 2: 'b'} == {2: 'b', 1: 'a'} is True.'", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q17" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "Directly addresses the core concept of the exam question which is currently completely unrepresented in the available snippets." + ], + "cons": [ + "Only unnecessary if we want students to guess based on general intuition that 'content is what matters', but that is risky for an exam." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:17", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating dictionary iteration using .items() (e.g., 'for k, v in d.items()') and clarifying that 'for x in d.items()' makes 'x' a tuple where 'x[1]' is the value. Also include a clear distinction between // (integer/floor division) and / (true division).", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q18" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This would directly enable the student to solve option C (understanding items and indexing) and D (recognizing why the division results in a different value/type)." + ], + "cons": [ + "If the student can guess that .items() provides both key and value and that x[1] follows standard indexing, but the division distinction is rarely intuitive to non-programmers." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:18", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Methods and Immutability. Content: Strings in Python are immutable; methods like .replace() return a NEW string rather than modifying the original. Usage: s.replace('old', 'new', 1) replaces only the first occurrence.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q19" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This directly addresses the mechanics required to solve the question: the need for assignment (s1 = ...) and the effect of the third argument." + ], + "cons": [ + "If the course assumes students already know basic string manipulation from earlier weeks, but the prompt specifies 'zero prior knowledge'." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:19", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Understanding **kwargs and .keys(). Code: def show_keys(**kwargs): return list(kwargs.keys()). Call: show_keys(first='val1', second='val2'). Output: ['first', 'second'].", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q20" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This would explicitly teach the student that the 'keys' in keyword arguments are the names used in the call, not the values assigned to them." + ], + "cons": [ + "One might argue that 'keys' is a semantically intuitive word, but in programming 'key' vs 'value' is a specific distinction that needs defining for a novice." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:2", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'String Manipulation Reference' card that explicitly shows: 1) 'text.split(\".\")' returns a list, 2) 'list[-1]' gets the last item, 3) 'text.find(\"x\")' returns an integer index.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q03" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "It allows a student with zero knowledge to logically evaluate why option 'a' fails (it splits on dots first, making the extension the last item) vs why 'b' and 'c' succeed (they isolate the host first)." + ], + "cons": [ + "The student can technically 'solve' the exam by just finding the exact match snippet provided." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:20", + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: Comparison Operators. x >= y means 'x is greater than or equal to y'. x < y means 'x is less than y'. Example: 0 >= 0 is True.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q21" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "Ensures a student with zero coding background doesn't second-guess the meaning of the mathematical symbols in Python." + ], + "cons": [ + "Most students recognize >= and < from basic math." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:21", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a topic card titled 'Lambda Functions and List Mapping'. It should show: 1. `list(map(lambda x: x*2, my_list))`, 2. `[ (lambda x: x*2)(i) for i in my_list ]`, and 3. `f = lambda x: x*2; [f(i) for i in my_list]`.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q22" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This would directly address all three options (a, b, and c) in the question, allowing a student to recognize the patterns as equivalent." + ], + "cons": [ + "Only unnecessary if the student is expected to already know basic functional programming concepts, but the prompt assumes zero knowledge." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:22", + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining 'enumerate(iterable)': 'The enumerate() function adds a counter to an iterable and returns it as an enumerate object. Example: for index, value in enumerate(['a', 'b']): print(index, value) outputs 0 a and 1 b.'", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q23" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "Directly explains how variables 'i' and 'j' are populated in the loop options (a and b)." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:23", + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining list comprehensions: '[expression for item in list if condition] creates a new list by applying the expression to each item that meets the condition.'", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q23" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "Enables the student to understand the syntax of Option C." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:24", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'prices = [10, 50, 20]; max_price = max(prices); best_index = prices.index(max_price); items = [\"apple\", \"pear\", \"banana\"]; print(items[best_index])'", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q24" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This directly demonstrates the index-retrieval pattern used in the correct answer (Option B)." + ], + "cons": [ + "If the student already understands that indices link related lists, they might guess it, but it's a specific technical hurdle." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:25", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'List Membership and Branching' with search text: 'To check if a value exists in a list, use the \"in\" operator: if item in my_list:. Use \"else:\" to handle cases where it is not found.'", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q01" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This directly teaches the 'zero-knowledge' student the exact syntax needed to choose Option A over the incorrect loop or return-based options." + ], + "cons": [ + "If the student is expected to deduce syntax from other exam questions not listed here." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:26", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining 'Iteration with Counters and Multiple Lists'. Examples: enumerate(mylist, start=1) and zip(listA, listB).", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q05" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This would allow a student to solve the problem by understanding the syntax (zip and enumerate) rather than just relying on finding a duplicate question." + ], + "cons": [ + "Since the duplicate question already exists in the exam bank, a student using the cheat sheet specifically for this course would likely find the direct answer anyway." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:27", + "kind": "edit_existing", + "target_item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "proposal": "Ensure the full text including the correct code segment and the explanation (why direct slicing fails) is visible in the snippet search text.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q06" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "It would provide the 'why' instead of just being a match, allowing the student to learn the underlying rule (no slicing on dicts)." + ], + "cons": [ + "The student can already find the answer by matching the exact question text." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:28", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining: 'In list comprehensions, [expression_if_true if condition else expression_if_false for item in list] transforms every item based on the condition.'", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q07" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "It directly addresses the syntax gap for conditional transformations in comprehensions." + ], + "cons": [ + "Clever students might infer the 'if-else' logic from general English, but formal confirmation is safer." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:29", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: labels = ['A', 'B']; msg = str(1) + labels[0]; print(msg). Explanation: str() converts numbers to text, '+' joins text, and [0] accesses the first item in a list.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q08" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This fills the 'zero-knowledge' gap regarding the specific syntax of list indexing and string building used in the question." + ], + "cons": [ + "Indexing and '+' for strings are often considered intuitive enough for students to guess correctly if they understand the loop." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:3", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Method Cheat Sheet' snippet: 1. Strings: .lower(), .replace(), .strip() return NEW strings. 2. Lists: .sort(), .append(), .reverse() return NONE (mutate in place). 3. Functions: sorted(x) returns a NEW sorted list, len(x) returns an int. 4. Warning: You cannot call .replace() on a list!", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q04" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This allows a student to solve the logic (Option D fails because it's a list; Option B/C fail because they return None) even if they don't find the exact duplicate question." + ], + "cons": [ + "The presence of the exact exam question in the database makes this redundant for this specific task." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:30", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Key Concept' snippet for List Slicing: 'To extract a portion of a list, use the syntax mylist[start:stop:step]. start is inclusive, stop is exclusive, and step determines the interval between elements. Example: x[1:10:2] starts at index 1 and takes every 2nd element.'", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q09" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This directly provides the syntax rules required to decode the question's blanks." + ], + "cons": [ + "Only unnecessary if the student has already covered basic sequence operations, but the prompt assumes zero prior knowledge." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:31", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Implicit Return Values' explaining: 'In Python, if a function completes its execution without hitting a return statement, it automatically returns the special value None.'", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q10" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This is the specific 'trick' of the question. Without this rule, a student with zero knowledge might assume the function causes an error or prints nothing." + ], + "cons": [ + "Advanced students might guess 'None' by process of elimination if they realize no other value is returned, but it is a specific language feature that warrants a snippet." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:32", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point or AI common question explaining built-in list methods: .index(item) to find a position, and clarify that indexing starts at 0.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q11" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This would allow the student to evaluate option 'c' (x.index(9)) which evaluates to 9." + ], + "cons": [ + "If the student infers that 'index' means 'position' and counts from 0, they might guess correctly, but it is not explicitly taught in the snippets." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:33", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing a function: def stats(*args):\n total = 0\n product = 1\n squares = []\n for n in args:\n total += n\n product *= n\n squares.append(n**2)\n return total, product, squares", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q12" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This covers every missing concept: the product identity (1), the *= operator, the ** exponentiation, and the append() method." + ], + "cons": [ + "If students are expected to know basic operators from other contexts, but for zero Python knowledge, this is critical." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:34", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining string formatting: 'The .format() method inserts values into strings. Positional placeholders like {0} and {1} correspond to the order of arguments in .format(first, second). Named placeholders like {name} require matching keywords in .format(name=\"value\").'", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q13" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "It directly enables a student to understand why Option A (positional) works and why Options C/D (named vs positional mismatch) fail." + ], + "cons": [ + "Only if the student already knows Python, but the goal is zero prior knowledge." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:35", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet illustrating the equivalence of df['col'], df.loc[:, 'col'], and df.iloc[:, col_index] for column selection.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q14" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "It directly addresses the core of the question (multiple ways to select the same data) which is a common pattern in introductory Python exams." + ], + "cons": [ + "Basic bracket notation is often sufficient for simple tasks, but this specific question tests 'all of the above' scenarios." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:36", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Datetime Formatting Reference' snippet: 'Use datetime.strptime(text, format) to read a date, and date.strftime(format) to write it. Format codes: %d=day, %m=month, %Y=year (e.g., \"%d-%m\" -> \"02-05\"). timedelta(days=n) adds or subtracts n days.'", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q15" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "It provides the exact translation key needed to interpret the input string and construct the output string." + ], + "cons": [ + "While Python-specific, some students might guess %m=month and %d=day, but it is risky without confirmation." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:37", + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet titled 'OOP: Calculated Attributes' showing a class Rectangle(width, height) that sets self.area = width * height. It should include a comment: 'Rectangle(2, 5) makes width=2, height=5, and area=10'.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q16" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "It directly mirrors the logic of the question (Shape with area = height * length), making the trace obvious to a non-programmer." + ], + "cons": [ + "The 'Vehicle' snippet covers 80% of the logic; the user might be able to 'jump' the remaining gap." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:38", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Sentence Reconstruction. Content: 'To turn a sentence into a list of words, use sentence.split(). To turn a list of words back into a sentence with spaces, use \" \".join(words_list).'", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q17" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This directly provides the syntax for the only two parts of the code not explained by the question's internal hints." + ], + "cons": [ + "A student might infer split/join from the context of the options, but it's a high cognitive load for zero-knowledge users." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:39", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a card for 'Essential String Methods' covering split(), join(), and replace().", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q18" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This would provide the direct definitions needed for all three code segments (a, b, and c) in the question." + ], + "cons": [ + "Only unnecessary if the user assumes the student can guess method names based on English meaning." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:4", + "kind": "edit_existing", + "target_item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "proposal": "Expand search_text to include the explanation: 'Option A is incorrect because .map() expects a function (like a lambda) or a dictionary to map values, not a pre-computed Series of the same length.'", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q05" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "It directly addresses the 'why' of the question, making the answer obvious to a student without prior knowledge." + ], + "cons": [ + "The student might be able to infer this from the generic .map() description in other snippets." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:40", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: df_filtered = df[(df['A'] > 5) & (df['B'] == 'Yes')] and df['New'] = ['High' if x > 10 else 'Low' for x in df['A']]", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q19" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This would directly illustrate the two most complex parts of the question: combining boolean filters and using list comprehensions for data transformation." + ], + "cons": [ + "The student might infer masking from the single-condition example, though the '&' operator is a specific technical hurdle." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:41", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Row-wise Calculations with Lambda. Content: To create a column based on multiple other columns, use df.apply(lambda row: expression, axis=1). For example: df['Total'] = df.apply(lambda r: r['A'] + r['B'] if r['C'] > 0 else 0, axis=1).", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q20" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This directly maps to the correct answer's pattern, explaining both the multi-column access (row['Col']) and the conditional logic." + ], + "cons": [ + "If the student is expected to infer lambda from general function application, but that is unlikely for a 'zero knowledge' persona." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:42", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Working with Datetimes. Content: Use `datetime.strptime(date_string, format)` to convert a string to a datetime OBJECT. Use `dt_object.strftime(format)` to convert it back to a STRING. Use `timedelta(days=n)` to add/subtract days from a datetime object.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q21" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This provides the missing technical knowledge required to understand why the code returns objects (Option B) instead of the desired strings." + ], + "cons": [ + "The topic might be covered in later weeks, but since the question is about Datetime Function 3, it's essential for this specific task." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:43", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Parsing Time Strings and Minute Arithmetic\nfrom datetime import datetime, timedelta\nstart_str = '9:30'\nh, m = start_str.split(':')\nstart_dt = datetime(2023, 6, 1, int(h), int(m))\nend_dt = start_dt + timedelta(minutes=20)\nprint(f'End: {end_dt.strftime(\"%H:%M\")}')", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q22" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This directly models the logic required in the __init__ method of the question, specifically the combination of string splitting, int conversion, and timedelta usage." + ], + "cons": [ + "A student might guess split() based on common sense, but the timedelta(minutes=...) syntax is hard to intuit without an example." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:44", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for a 'Circle' class that has a 'radius' attribute, an 'area(self)' method, and a 'summary(self)' method that returns f'Area is {self.area()}'.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q23" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "This would explicitly teach the student that methods need 'self' as an argument and 'self.' prefix with parentheses to be called, directly addressing the distractors in options C and D." + ], + "cons": [ + "It is a fundamental OOP concept, but 'zero knowledge' students require an explicit code example of method-to-method calling." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:45", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet (e.g., 'OOP Method with List and Enumerate') that shows a class 'Inventory' with an 'items' list, an 'add_item' method using '.append()', and a 'get_indexed_items' method returning a dictionary using 'enumerate(self.items, start=1)'.", + "source_question_ids": [ + "final-exam-study-guide-trial-python-basics-2023-q24" + ], + "source_exams": [ + "final-exam-study-guide-trial-python-basics-2023" + ], + "pros": [ + "Directly demonstrates the mechanics needed to solve '9_OOP_Hard_2', specifically list mutation and dictionary generation with custom start indices." + ], + "cons": [ + "If the student already understands list basics from a separate 'Lists' section, this might be redundant, but for zero-knowledge students, this bridge is vital." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:46", + "kind": "add_new", + "target_item_id": "", + "proposal": "Arithmetic and Logic Basics: Explain that 'x % 2 == 0' checks if a number is even (no remainder) and 'x % 2 != 0' checks if it is odd. Explain that range(11) creates numbers 0 to 10.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q01" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This allows the student to verify Option B and Option A independently rather than relying on a verbatim question match." + ], + "cons": [ + "If the goal is purely 'cheating' by pattern matching, the existing verbatim snippet is sufficient." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:47", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Nested Functions and Enclosing Scope. Content: Python allows defining a function (inner) inside another function (outer). The inner function can access variables defined in the outer function (its enclosing scope) as well as global variables. Example: def outer(x): y=10; def inner(z): return x+y+z; return inner.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q02" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "It explains the structure of the code context, which involves nested functions—a concept not explicitly covered in the 'Global vs Local' snippet." + ], + "cons": [ + "A student might simply follow the trace in the existing exam-match snippet without needing the formal definition of nested scopes." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:48", + "kind": "edit_existing", + "target_item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "proposal": "Update the search_text/content to include the correct code segment: 'roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}'.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q04" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "It provides the direct answer and the exact syntax for the comprehension + zip pattern." + ], + "cons": [ + "If the goal is to teach the principle rather than give the answer, a generic zip-comprehension example might be better." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:49", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a summary snippet for 'Dictionary Comprehensions' showing: {k: v for k, v in zip(keys, values)} and explaining that range(1, 6) produces 1, 2, 3, 4, 5.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q04" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "It bridges the gap between the individual components (zip and comprehension) and explains the range function logic." + ], + "cons": [ + "None; this is a core missing piece for zero-knowledge users." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:5", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating element-wise subtraction: df['diff'] = df['X'] - df['Y'].", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q06" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "It removes the slight leap of faith required to assume '-' works exactly like '+'." + ], + "cons": [ + "The 'sum' example is already extremely suggestive of the correct answer." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:50", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Syntax' card for the 'zip()' function that shows: for x, y in zip(list1, list2): ...", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q05" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "It clarifies how the loop in the correct answer manages to access both 'name' and 'age' simultaneously without using an index variable." + ], + "cons": [ + "The student might infer the behavior from the context of the question/answer pair, but a definition ensures certainty." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:51", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Max/Min Patterns' reference card. Example: To find the key with highest value, use max_val = max(d.values()) then loop if val == max_val. To find highest key alphabetically, use max(d).", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q06" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This helps a student solve variants of the question (e.g., finding the lowest rating) without relying on seeing the exact problem beforehand." + ], + "cons": [ + "The student already has the exact answer in the existing exam snippet." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:52", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'The zip(a, b) function creates pairs of elements from two lists. item[0] refers to the first element in the pair, and item[1] to the second. Multiplying a string by an integer (e.g., \"a\" * 3) repeats the string that many times (\"aaa\").'", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q08" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "Directly addresses the two most obscure parts of the question for a beginner: zip and string multiplication." + ], + "cons": [ + "Only if the student is expected to guess that 'multiplication' of a string and number behaves like repetition." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:53", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Slicing Cheatsheet' snippet: 'Python slicing follows the format list[start:stop:step]. Start is inclusive, stop is exclusive. Indices can be negative: -1 is the last element, -2 is second-to-last. Example: mylist[0:5:2] takes every 2nd element from index 0 up to (but not including) index 5.'", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q09" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This provides the exact mechanical rules required to solve any slicing problem without prior coding experience." + ], + "cons": [ + "If the goal is only to provide existing exam examples, but those examples currently lack explanatory power for this specific problem." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:54", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Using Enumerate' with code: `for index, char in enumerate('abc'): print(index, char)`. Explanation: 'enumerate' gives the position (0, 1, 2) and the character ('a', 'b', 'c') at the same time.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q10" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "Directly explains the 'untraceable' part of the question for a beginner." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:55", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for the 'in' operator: `if 5 in [1, 5, 10]: # This is True`. Explanation: The 'in' keyword checks if a value exists inside a list.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q10" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "Explains the conditional logic `if index in x` which determines which letters are appended." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:56", + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet demonstrating 'len()' on a string and the difference between '/' and '//' operators, as well as basic '[0]' indexing.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q11" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This would allow a student to solve Option C (len and floor division) and Option B (indexing the result of a split)." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:57", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new AI Example titled 'Numeric Operations and Tuples'. Content: 'To square a number use x**2. To check if a number is even, use num % 2 == 0. To return two values together, use return (value1, value2).'", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q12" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This directly addresses the missing syntactical knowledge required to verify the math in Option A vs Option B." + ], + "cons": [ + "The student might guess the meaning of % and ** from context or general programming knowledge, but for 'zero prior knowledge', it is essential." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:58", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Python String Formatting' that includes: 1. f-strings: f'Hello {name}', 2. .format(): 'Hello {}'.format(name), and 3. Concatenation: 'Hello ' + name + ' is ' + str(age).", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q13" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This would directly allow a student to recognize that all three options in the exam question perform the same task correctly." + ], + "cons": [ + "If the student has already seen these in basic lecture notes, but the goal is to help a student with 'zero prior knowledge' using only snippets." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:59", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet from Week 5 lecture materials (Inspecting and Selecting Data) that states: 'When selecting a single column from a DataFrame: using a string label (e.g., df['A']) returns a Series, while using a list of one label (e.g., df[['A']]) returns a one-column DataFrame.'", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q14" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This directly addresses the core concept of the exam question regarding return types." + ], + "cons": [ + "If the goal is only to provide exam question examples, adding a theoretical rule might deviate from the current snippet style." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:6", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a conceptual snippet titled 'Pandas Selection Rules' that explains: 1. .loc[start:stop] is label-based and INCLUDES stop. 2. .iloc[start:stop] is zero-indexed position-based and EXCLUDES stop. 3. Boolean masks return only rows where the condition is True.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q07" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This provides the 'rules of the game' that allow a student to logically deduce why Option A includes row 2 (label 2) while Option D starts at row 3 (position 2)." + ], + "cons": [ + "If the student finds the full solution in the expanded 'Trial' exam snippet (item 6), they might just memorize the answer pattern." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:60", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Formatting Cheatsheet' snippet. It should show: %Y (Year 2023), %m (Month 01-12), %d (Day 01-31), %H, %M, %S. Include an example: datetime.strptime('2023-06-01', '%Y-%m-%d').", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q15" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This allows students to translate the strings in the options into actual dates and compare them to the original code's dates." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:61", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing a class where attributes are set conditionally, e.g., 'if age > 18: self.status = \"adult\" else: self.status = \"minor\"'.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q16" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "It directly mirrors the 'logic-heavy' constructor pattern seen in this exam question, reducing the mental leap for a novice." + ], + "cons": [ + "Basic OOP and Basic Conditions are present, and their combination is logically intuitive." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:62", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: separator = '-'; words = ['a', 'b', 'c']; result = separator.join(words).", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q17" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "It would allow the student to see that .join() is called on the string separator and takes only the list as an argument, making the error in ' '.join(word_list, '-') (two arguments) obvious." + ], + "cons": [ + "Process of elimination might be sufficient for an exam setting if all other operations are clearly validated." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:63", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new 'String Operations' snippet that covers: 1. str.replace(old, new) for substitution. 2. str.capitalize() and str.title() for casing. 3. '+' for joining strings. 4. An explicit note that strings cannot be modified in-place (no sentence[i] = 'X').", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q18" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This question tests basic string method knowledge. Without a reference to these specific methods, a student cannot confidently select 'd' over 'a' or 'c'." + ], + "cons": [ + "It is only unnecessary if the student has access to the full Python documentation or has already memorized basic string syntax." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:64", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet illustrating: 1) Using .map(lambda x: x[-n:]) to extract suffixes. 2) Using list comprehension [value if condition else other for x in series] to replace specific values in a column. 3) Comparing .map(len) vs map(lambda x: len(x)).", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q19" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This would directly address the 'hard' components of the question (Operations 2 and 3) which are currently unsupported by the recommended snippets." + ], + "cons": [ + "Basic pattern matching might lead a student to Option A, but they wouldn't understand 'why' it works without these concepts." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:65", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: df = df.sort_values(by='col', ascending=False) with a comment: '# Sorts the table by the values in \"col\", from highest to lowest'.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q20" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "Essential for determining which rows appear first in the final output (Product C then A)." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:66", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining lambda: 'df[\"A\"].map(lambda x: x*2) means apply the rule \"take x and return x times 2\" to every row in column A'.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q20" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "The most difficult syntactic hurdle for a zero-knowledge student in this specific problem." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:67", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: 'from datetime import datetime, timedelta; dt = datetime.strptime(\"23-03-2026 14:00\", \"%d-%m-%Y %H:%M\"); end = dt + timedelta(minutes=30)'.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q21" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This would allow a student to verify the syntax for parsing (strptime) and time addition (timedelta) used in the question." + ], + "cons": [ + "The question hint provides some info on timedelta, but not on strptime or format strings." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:68", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining the logic for checking if two time intervals (start1, end1) and (start2, end2) overlap: 'start1 < end2 and end1 > start2'.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q21" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "This is a common exam pattern that is difficult to deduce with zero prior logic/programming knowledge." + ], + "cons": [ + "Some students might be able to figure this out logically if they draw it, but it's a high cognitive load." + ], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:69", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Datetime Attribute Extraction and Formatting'. Content: 'Given dt = datetime(2023, 1, 1), use dt.day, dt.month, and dt.year to get integers. Use dt.strftime(\"%d-%m-%y\") to create a formatted string like \"01-01-23\".'", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q22" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "Directly provides the information needed to distinguish between the datetime object (needed for attributes) and the formatted string (needed for the index)." + ], + "cons": [ + "The student might guess based on the intuitive names of '.day' and '.year', but they wouldn't know 'strftime' or how it differs from a raw object." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:7", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas Filtering and Sorting. Content: Use df.loc[condition] to filter rows. Conditions: df['col'] == 'val', df['col'].isin(['a', 'b']), or ~ (not). Use df.sort_values('col', ascending=False) to sort by a column in descending order.", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q08" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "It directly explains the functions used in the exam question options (isin, sort_values, ascending)." + ], + "cons": [ + "If this information is expected to be in a lecture-based summary snippet that was simply not included in this search batch." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:70", + "kind": "add_new", + "target_item_id": "", + "proposal": "A reference card for Python Arithmetic Operators: + (addition), - (subtraction), * (multiplication), / (division), // (floor division/integer), % (modulo). Include an example like '15 // 4 = 3 (fits 3 times)'.", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q23" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "The question hinges on calculating how many times something 'fits completely', which requires // instead of /." + ], + "cons": [ + "Students might infer // is 'special' for integers given the context 'Amount: 3' in the example output." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:71", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining 'self' and tuple indexing. Example: 'In Python classes, self.attribute refers to the data stored in that object. If a variable represents a position like (row, col), position[0] gets the row and position[1] gets the col.'", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q24" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "The question relies heavily on understanding that initial_position[0] is a number being subtracted from target_position[0]. Without knowing what the brackets do, the math is impossible to trace." + ], + "cons": [ + "Some students might guess indexing based on other languages, but it's risky for zero-knowledge users." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:72", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for common built-in functions: 'abs(x) returns the absolute (positive) value of a number. For example, abs(-3) is 3.'", + "source_question_ids": [ + "introduction-to-python-trial-final-exam-solutions-py22-q24" + ], + "source_exams": [ + "introduction-to-python-trial-final-exam-solutions-py22" + ], + "pros": [ + "The logic for distance (row_diff > 3) and diagonal movement (abs(row_diff) == abs(col_diff)) requires knowing what abs() does." + ], + "cons": [ + "Abs is common in math, but its specific Python syntax should be confirmed." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:73", + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Python List & Tuple Indexing. 1. Indexing starts at 0. 2. Negative indices count from the end (-1 is the last item, -2 is second to last). 3. For nested structures like x = [(a, b)], x[0][1] accesses the second item of the first tuple.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This would allow the student to understand *why* x[0][1] is 2, rather than just relying on a matched example." + ], + "cons": [ + "The exact question already exists in the exam bank snippets, so for this specific exam, the student can just match the pattern." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:74", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'List Methods and Return Values': Common list methods like .append(), .remove(), and .sort() perform actions 'in-place'. This means they change the list but return the value None. If you see code like 'print(mylist.append(5))' or 'return [mylist.append(5)]', the output will be None or [None].", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This addresses the specific 'trap' in the question that separates students who understand loop logic from those who understand Python's method return conventions." + ], + "cons": [ + "It is a very specific technical detail, but it is a recurring theme in 'Return Behavior' exam questions." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:75", + "kind": "edit_existing", + "target_item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "proposal": "Update search_text to include: 'Option B uses slicing [::-2] to step backwards through the list by 2, which skips the duplicates and reverses the order.'", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "It clarifies the 'magic' of the slicing syntax which is currently truncated in the snippet." + ], + "cons": [ + "The student might infer the result because it is a direct match of a known exam question." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:76", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Dictionary & **kwargs Iteration. Content: 'def main(**kwargs): \\n # kwargs.keys() -> names (strings)\\n # kwargs.values() -> values (numbers/data)\\n # kwargs.items() -> both (name, value)\\n for val in kwargs.values(): total += val'", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This directly addresses the trap in the exam question by explaining the return types of dictionary methods." + ], + "cons": [ + "If the student already understands basic dictionary concepts from a general programming background, they might guess correctly, but for a zero-knowledge student, this is essential." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:77", + "kind": "edit_existing", + "target_item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "proposal": "Expand search_text to include the solution logic: 'To sum prices passed as keywords, iterate over kwargs.values() to get the numbers, not the keys.'", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "Turns a placeholder into a functional solution reference for that specific recurring exam question." + ], + "cons": [], + "recommended_direction": "consider_instead", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:78", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Key Point' explaining Dictionary Comprehensions: '{k: v for k in list}' where 'k' is the key and 'v' is the value. Emphasize that the key comes before the colon.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "It gives the student the 'rule' instead of just a specific answer, allowing them to solve variations of the question." + ], + "cons": [ + "The direct match in the exam snippets might be enough for a student looking for a quick fix." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:79", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Analytics' snippet: 'To calculate average: avg = sum(my_dict.values()) / len(my_dict). To find items above average: for key in my_dict: if my_dict[key] > avg: print(key). Note: for key in my_dict is the same as for key in my_dict.keys().'", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "It explains the underlying logic of the two options (A and B) in the question, clarifying why they are functionally identical despite different syntax." + ], + "cons": [ + "The student might just rely on matching the exact question if they find snippet 4." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:8", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: my_dict = {item.split(':')[0]: int(item.split(':')[1]) for item in my_list}", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q09" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "This matches the exact syntax pattern used in Option A, allowing a student to recognize the structure." + ], + "cons": [ + "Some students might infer it from the 'word_lengths' question if the solution to that question used a comprehension." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:80", + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: String Case Testing. .islower() returns True ONLY if the character is a lowercase letter. It returns False for uppercase letters, spaces, and punctuation (e.g., 'a'.islower() is True, but 'A', ' ', and '!' are False).", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "Directly explains why spaces and punctuation are excluded from the result list in the question." + ], + "cons": [ + "A student might guess 'islower' refers only to lowercase letters, but 'zero knowledge' implies they might not know if a comma has a case." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:81", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Python Arithmetic Operators. Content: + (addition), - (subtraction), * (multiplication), / (division), // (floor division: divides and rounds down to nearest integer), % (modulo: remainder), ** (exponentiation). Example: 5 // 2 results in 2.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "Directly explains the // operator used in the code context to reach the correct answer." + ], + "cons": [ + "Basic math might be assumed, but floor division is specific to programming languages." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:82", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Parallel Iteration with zip(). Content: The zip() function takes multiple iterables (like lists) and aggregates them into tuples. Example: for a, b in zip([1, 2], [3, 4]): prints (1, 3) then (2, 4).", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "Explains how the 'for a, b in zip(list1, list2)' loop processes both lists simultaneously." + ], + "cons": [ + "None; it is critical for this specific question." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:83", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Nested Slicing Logic. Content: Slicing creates a new list. You can apply another slice immediately after: my_list[start:stop:step][new_start:new_stop:new_step]. The second slice acts on the results of the first.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This helps the student evaluate options A and C which use two sets of brackets." + ], + "cons": [ + "The student might just find the exact matching question snippet and stop there." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:84", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card titled 'Targeted String Modification' showing: 1. .replace('text', 'new', 1) only replaces the first match; 2. .find('text', 5) starts searching after index 5; 3. sentence[:5] + 'new' + sentence[10:] replaces characters between index 5 and 10.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This directly maps to the mechanics of both Option A and Option B, allowing a student to verify the multi-step replacement logic in Option B and the slicing offsets in Option A." + ], + "cons": [ + "The question contains a hint for find(), but it is insufficient for a zero-knowledge student to confidently evaluate the replace() logic or the math behind index+4 slicing." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:85", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: f'Items: {items[0]}, {items[1]}' and comparing it to ', '.join(items).", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This directly addresses the core logic of the question: distinguishing between a simple join and specific formatting requirements like 'and' before the last item." + ], + "cons": [ + "If the student has access to a 'String Fundamentals' cheat sheet section not included in these exam snippets." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:86", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: data = {'col1': [1, 2], 'col2': [3, 4]}; df = pd.DataFrame(data). Include a brief note on using .split() to break strings into list components.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This directly bridges the gap between having extracted components and returning them as a structured DataFrame, which is the core task of the exam question." + ], + "cons": [ + "Option D uses pd.Series explicitly, so a student might guess the DataFrame structure if they understand Series, but the dictionary-to-DataFrame mapping is a common stumbling block." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:87", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: 'class User: def __init__(self, id, status=\"active\"): self.id = id; self.status = status; u = User(123); print(u.status == \"active\")'", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This merges OOP structure with default argument logic and attribute access in one clear example, mirroring the question's complexity." + ], + "cons": [ + "The student can technically deduce the answer by combining the 'Arguments' and 'OOP Fundamentals' snippets currently available." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:88", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'dt = datetime.strptime(\"2023/01/10\", \"%Y/%m/%d\")' with a comment explaining that %Y is year, %m is month, and %d is day.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "It removes any ambiguity for a non-Python user about how the string '2023/1/10' is being processed." + ], + "cons": [ + "Most students will correctly guess that '2023/1/10' represents January 10, 2023, without needing the technical definition of strptime." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:89", + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas Selection Cheat Sheet. Content: To select one column: df['A']. To select multiple: df[['A', 'B']]. To select specific rows and columns by label: df.loc[row_index, 'column_name']. Note: Using df[index, 'column'] directly results in an error.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "It directly addresses the core logic required to distinguish between valid Pandas syntax and the error-inducing Option D in the exam question." + ], + "cons": [ + "If the goal is only to use existing exam questions as context, but since the current questions are truncated, they don't provide the syntax rules clearly." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:9", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: result = dict(zip(keys_list, values_list))", + "source_question_ids": [ + "final-exam-solutions-for-python-programming-62oop21-q09" + ], + "source_exams": [ + "final-exam-solutions-for-python-programming-62oop21" + ], + "pros": [ + "Explicitly validates Option B's logic for students who have never seen zip()." + ], + "cons": [ + "Option B is quite intuitive if 'zip' is assumed to 'pair things up', but for zero-knowledge, it needs proof." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:90", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Instance Methods and Conditional Returns' that shows: 1. A method using self. 2. A return statement using the 'X if condition else Y' syntax. 3. A warning that '=' cannot be used for comparison in 'if' statements.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This would directly address the syntax found in the correct answer (ternary) and the syntax error in the most tempting distractor (Option B)." + ], + "cons": [ + "If the student is very observant, they might infer 'self' from the constructor snippets, but the ternary operator is likely to be confusing." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:91", + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Datetime and Timedelta Operations'. Key points: 1. datetime.strptime() returns a datetime object. 2. datetime.strftime() returns a string. 3. Adding a timedelta to a datetime object works; adding it to a string causes a TypeError.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "It explicitly provides the technical knowledge needed to evaluate Option C, which is the correct answer and the core 'trick' of the question." + ], + "cons": [ + "If this is a rare topic, but since it appears in final exams, it is high-value." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:92", + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: 'Datetime Construction and Formatting'. Content: 'from datetime import datetime; # Order: Year, Month, Day; dt = datetime(2023, 5, 1); # Format to string; s = dt.strftime(\"%d-%m-%Y\") # Returns \"01-05-2023\"'.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This provides the exact 'missing piece' regarding argument order and method selection (strftime) needed to solve the exam question." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:93", + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Pandas Aggregation and Filtering. 'To calculate the average of a column, use df[col].mean(). To filter a DataFrame to show only rows where a condition is met, use df[df[col] > value] or df[df[bool_col] == True].'", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "It directly connects the 'average' requirement in the question to the '.mean()' method and explains the filtering syntax needed for Operation 3." + ], + "cons": [ + "The 'extra_practice' snippet mentions 'above average' logic for dictionaries, but Pandas-specific syntax is distinct enough to warrant its own entry." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:94", + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Lambda Functions in Pandas. 'lambda x: expression' creates a small anonymous function where 'x' represents the value of each row/element when used with .map() or .apply(). Example: s.map(lambda x: x + 10).", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "This is critical for understanding what the 'lambda' keyword does in the question code." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:95", + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Pandas Aggregations. Methods like .sum(), .mean(), and .count() return a single number representing the total/average/count of the entire Series/column. Example: df['B'].sum() equals the sum of all values in column B.", + "source_question_ids": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24" + ], + "source_exams": [ + "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023" + ], + "pros": [ + "The student needs to know that df['B'].sum() is a constant value (15) in this context, not another Series." + ], + "cons": [], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:96", + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "proposal": "Ensure the text includes: 'Option B uses slicing [::-2], which starts from the end of the list and takes every second element, resulting in [5, 4, 3, 2, 1].'", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q05" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "It allows a zero-knowledge student to manually verify the slicing result rather than just taking the snippet's word for it." + ], + "cons": [ + "The student may already be convinced by the explanation of Option A and the knowledge that 'Both' is an option." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:97", + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-6-w3-arguments", + "proposal": "Append the correct code solution and a brief explanation: 'Use **kwargs to capture keyword arguments as a dictionary; use kwargs.values() to iterate over and sum only the values (prices).'", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q06" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "It directly answers the 'how' for a student who recognizes the problem but doesn't know the specific dictionary method names." + ], + "cons": [ + "The student might infer it if they have a general 'Dictionary Methods' snippet elsewhere, but specialized **kwargs help is better." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:98", + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "proposal": "Update the search_text to include the full solution code for option C: word_lengths = {word: len(word) for word in words}.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q07" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "The current snippet cuts off at 'Option A is a vali', which might lead a student to think A is the answer, even though the provided question says C is correct." + ], + "cons": [ + "Snippet 16 provides the conceptual backing, but clarity is always better." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + }, + { + "suggestion_id": "round1:99", + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Key Point' snippet titled 'Counting with Dictionaries' that explains: To count items, check if the item is a key. If not, set it to 0. Then, increment by 1.", + "source_question_ids": [ + "resit-solutions-for-introduction-to-python-35761538-q08" + ], + "source_exams": [ + "resit-solutions-for-introduction-to-python-35761538" + ], + "pros": [ + "This would allow a student to solve the problem by understanding the logic rather than just finding the identical question in the database." + ], + "cons": [ + "The direct match snippet already ensures the student can answer the specific exam question correctly." + ], + "recommended_direction": "add_this", + "human_review_status": "pending" + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-solutions-for-python-programming-62oop21.json b/data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-solutions-for-python-programming-62oop21.json new file mode 100644 index 0000000..550961d --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-solutions-for-python-programming-62oop21.json @@ -0,0 +1,2142 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q01", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q01", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "Take a look at the following class definition.\n\nclass Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nGiven the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\nWhy?", + "options": { + "a": "The first argument (my_flight) should not have been passed to the set_date method in Code line 2.", + "b": "The capacity of the flight is not specified as an argument in Code line 1.", + "c": "The argument self is missing in Code line 1.", + "d": "The date string passed as an argument in Code line 2 represents an invalid date." + }, + "correct": "a", + "explanation": "set_date is an instance method, so Python passes self automatically. Passing my_flight explicitly adds an extra argument and causes the error.", + "code_context": "class Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\")\nmy_flight.set_date(my_flight, \"29-02-2022\")" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Given the class definition above, trying to execute the following two code lines will result in a Python error. my_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1 my_fli", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "kp-4", + "rationale": "This snippet explicitly describes the exact error pattern in the question (obj.set_date(obj, x)) and explains that it passes 'one argument too many' because self is passed automatically." + }, + "top_three_snippets": [ + { + "item_id": "kp-4", + "rationale": "Directly explains the mechanical error of passing the instance explicitly in a method call." + }, + { + "item_id": "manual-method-call", + "rationale": "Provides a clear conceptual explanation of why Python adds the instance automatically and how manual inclusion results in an argument count error." + }, + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Matches the exact code and scenario from the exam question, providing a direct reference for the student." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "kp-4", + "rationale": "Provides the rule and the specific error syntax." + }, + { + "item_id": "ks-9e278d1ee6", + "rationale": "Explains what 'self' is, which helps a novice understand why the parameter exists in the definition but is omitted in the call." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet kp-4 and manual-method-call explicitly address the 'extra argument' error caused by passing the object instance manually, which is the core concept of the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage for this specific concept (automatic self-passing vs manual passing errors) is excellent.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:41:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q02", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q02", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "You have the following definition for a Book class.\n\nclass Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)\n\nSuppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book. The compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?", + "options": { + "a": "def compare(self, other):\n avg_better = self.average_score() > other.average_score()\n no_fewer_reviews = self.num_reviews() >= other.num_reviews()\n if avg_better and no_fewer_reviews:\n return self.title\n elif not avg_better:\n return other.title\n else:\n return None", + "b": "def compare(self, other):\n for first, second in [(self, other), (other, self)]:\n avg_better = first.average_score() > second.average_score()\n no_fewer_reviews = first.num_reviews() >= second.num_reviews()\n if avg_better and no_fewer_reviews:\n return first.title\n return None", + "c": "Both methods above compare the book objects as intended.", + "d": "Neither of the two methods above compare the book objects as intended." + }, + "correct": "b", + "explanation": "B checks whether either book is better than the other and returns that title, otherwise it returns None. A can incorrectly return the other book even when neither book is better.", + "code_context": "class Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another b", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet contains the exact logic requirements for the 'better than' comparison (average score higher AND at least as many reviews), which is the core of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Defines the specific business logic/rules the student must implement." + }, + { + "item_id": "manual-oop-state-compare", + "rationale": "Provides a nearly identical class structure (Book, add_review, average) allowing a student to understand how methods are called on instances." + }, + { + "item_id": "manual-oop-init-defaults", + "rationale": "Helps a student understand attribute initialization (self.title, self.review_scores), which is necessary to understand what the options are returning." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Logic rules." + }, + { + "item_id": "manual-oop-state-compare", + "rationale": "Structural context." + }, + { + "item_id": "manual-oop-init-defaults", + "rationale": "Attribute context." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain the rules and the class structure, but they don't explicitly teach the 'symmetric comparison' pattern used in Option B. A student might struggle to realize that Option A is logically flawed (it assumes if self isn't better, the other must be) without a snippet explaining mutual exclusion in complex conditions.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets provide the 'what' (rules) and the 'where' (class), but miss the 'why' regarding the logical structure of comparison functions.", + "missing_concepts": [ + "Symmetric comparison logic", + "Handling 'None' as a fallback when multiple conditions aren't met", + "Logical fallacies in multi-attribute comparison" + ], + "proposed_fix": "Add an AI example snippet showing a comparison method between two objects that returns None if neither meets a strict 'better' criteria." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: 'Comparing Objects with Multiple Criteria'. Snippet: 'When comparing two objects (A, B) based on multiple rules, remember that ! (A > B) does not imply (B > A). Example: def compare(self, other): if self.val > other.val and self.count >= other.count: return self; if other.val > self.val and other.count >= self.count: return other; return None'", + "why_helpful": "This directly addresses the logical pitfall in Option A and explains the necessity of the structure in Option B.", + "why_maybe_unnecessary": "Some students might infer the logic if they are strong in general boolean reasoning.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:41:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q03", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q03", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?", + "options": { + "a": "def get_tld(url):\n url_1 = url.split(\".\")[-1]\n return url_1.split(\"/\")[0]", + "b": "def get_tld(url):\n url_1 = url.split(\"//\")[1]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]", + "c": "def get_tld(url):\n return url.split(\"//\")[1].split(\"/\")[0].split(\".\")[-1]", + "d": "def get_tld(url):\n url_1 = url[url.find(\"www\") + 2:]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]" + }, + "correct": "a", + "explanation": "A splits on the last dot first, which leaves the page extension rather than the domain. The other options isolate the host name first and then extract the final dot-separated part.", + "code_context": "def get_tld(url):\n # Extract the top-level domain from a URL string" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following form", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the exact same question as the one being asked. It provides the problem statement, format, and logic required to solve the task." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Direct match for the question; provides the exact context and structure of the expected answer." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "While the topic says 'Conditions', the content is about string methods and 'does NOT achieve' logic, which mirrors the question's structure." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Another string-processing function question that helps a student understand how functions manipulate string inputs to produce specific outputs." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Since this is the exact question, it is technically sufficient for a student to find the answer by pattern matching." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the candidate list. A student can simply match the 'get_tld' function name and the URL format to the snippet to find the answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact answer is present, there is a conceptual gap in explaining how the '.split()' method, negative indexing ([-1]), and 'find()' actually work.", + "missing_concepts": [ + ".split() method behavior", + "Negative indexing in strings/lists ([-1])", + "String slicing with [start:]", + ".find() method return values" + ], + "proposed_fix": "Add a conceptual snippet or 'cheat sheet' card explaining string slicing and the split method, as these are the primary tools used in all options (a, b, c, d)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'String Manipulation Reference' card that explicitly shows: 1) 'text.split(\".\")' returns a list, 2) 'list[-1]' gets the last item, 3) 'text.find(\"x\")' returns an integer index.", + "why_helpful": "It allows a student with zero knowledge to logically evaluate why option 'a' fails (it splits on dots first, making the extension the last item) vs why 'b' and 'c' succeed (they isolate the host first).", + "why_maybe_unnecessary": "The student can technically 'solve' the exam by just finding the exact match snippet provided.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:42:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q04", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q04", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "def is_anagram(word_1, word_2):\n return sorted(list(word_1.replace(\" \", \"\").lower())) == sorted(list(word_2.replace(\" \", \"\").lower()))", + "b": "def is_anagram(word_1, word_2):\n return word_1.replace(\" \", \"\").lower().sort() == word_2.replace(\" \", \"\").lower().sort()", + "c": "def is_anagram(word_1, word_2):\n return list(word_1.replace(\" \", \"\").lower()).sort() == list(word_2.replace(\" \", \"\").lower())", + "d": "def is_anagram(word_1, word_2):\n return sorted(list(word_1)).replace(\" \", \"\").lower() == sorted(list(word_2)).replace(\" \", \"\").lower()" + }, + "correct": "a", + "explanation": "A removes spaces, lowercases both strings, and compares the sorted letters. The other options misuse sort() or apply string operations to list objects in the wrong order.", + "code_context": "def is_anagram(word_1, word_2):\n # Compare the same letters in normalized, sorted form" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be writt", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-4-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 4, + "question_summary": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be writt", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-4-w2-conditions", + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This snippet is the exact same question from a previous exam. It provides the full code for is_anagram, identifies the correct answer (a), and explains that .sort() misuses return values while sorted() is correct for comparisons." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Identical previous exam question providing the exact logic and explanation needed." + }, + { + "item_id": "aiq-4", + "rationale": "Provides a critical conceptual warning to check if methods mutate in place, which is the primary 'trap' in options B and C (using .sort())." + }, + { + "item_id": "aiq-2", + "rationale": "Reinforces the concept of in-place mutation vs. return values for list operations, helping a student distinguish between .sort() and sorted()." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Directly answers the question with zero inference required." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the identical question from a past exam, which contains the correct implementation and a clear explanation of why the alternatives are wrong.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The exact answer is present, but the student relies on finding that specific match. General rules about method chaining and type-specific errors (like calling .replace() on a list) are not explicitly summarized.", + "missing_concepts": [ + "Explicit rule that .sort() returns None (causing comparisons to fail).", + "Explicit rule that string methods (.replace, .lower) cannot be called on list objects returned by sorted()." + ], + "proposed_fix": "Add a summary card focused on 'Method Chaining & Return Values' specifically comparing string methods vs. list methods." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Method Cheat Sheet' snippet: 1. Strings: .lower(), .replace(), .strip() return NEW strings. 2. Lists: .sort(), .append(), .reverse() return NONE (mutate in place). 3. Functions: sorted(x) returns a NEW sorted list, len(x) returns an int. 4. Warning: You cannot call .replace() on a list!", + "why_helpful": "This allows a student to solve the logic (Option D fails because it's a list; Option B/C fail because they return None) even if they don't find the exact duplicate question.", + "why_maybe_unnecessary": "The presence of the exact exam question in the database makes this redundant for this specific task.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:42:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q05", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q05", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "Pandas", + "question": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "s.map((s - s.mean())**2)", + "b": "(s - s.mean())**2", + "c": "s.map(lambda x: (x - s.mean())**2)", + "d": "(s - s.mean()).map(lambda x: x**2)" + }, + "correct": "a", + "explanation": "A is not the right way to apply the squared-difference expression to each element of the Series. B, C, and D all produce the desired squared differences.", + "code_context": "# s is a pandas Series of floats" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the correspondin", + "score": 3, + "evidence_item_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "It explicitly explains that the .map() method is used to apply a function. This allows a student to deduce that passing a pre-calculated Series (Option A) is incorrect." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Clarifies that .map() expects a function, which is the core reason why Option A is the answer." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Explains that vectorized operations in Pandas are performed directly on columns/Series, validating Option B." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Provides an example of applying squaring functions to elements, helping the student understand the logic in Options C and D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Defines .map() as a tool for applying functions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Defines vectorized math for Pandas structures." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets explain what .map() and vectorized operations are, the student must still perform the logical step of identifying that a Series object is not a 'function' to eliminate Option A.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover the 'how' for the correct options but don't explicitly warn against the common mistake of passing a Series into .map().", + "missing_concepts": [ + "The distinction between passing a function vs. a Series/array to the .map() method." + ], + "proposed_fix": "Update the exact-match snippet to include its original explanation, which highlights that A is not the right way to apply expressions." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "proposal": "Expand search_text to include the explanation: 'Option A is incorrect because .map() expects a function (like a lambda) or a dictionary to map values, not a pre-computed Series of the same length.'", + "why_helpful": "It directly addresses the 'why' of the question, making the answer obvious to a student without prior knowledge.", + "why_maybe_unnecessary": "The student might be able to infer this from the generic .map() description in other snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:43:12Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q06", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q06", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-2", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the difference of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] - df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x - df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\"] - df.columns[\"B\"]", + "d": "df[\"C\"] = df.apply(df[\"A\"] - df[\"B\"])" + }, + "correct": "a", + "explanation": "Subtracting one numeric Series from another directly creates the elementwise difference needed for column C.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This snippet describes the exact same scenario (creating column C from columns A and B) using the 'sum' operation. A student can easily deduce that replacing '+' with '-' performs subtraction." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides the structural template for vectorized column creation (A + B) which directly maps to the question (A - B)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces the concept of vectorized operations in Pandas, explicitly mentioning 'Vectorized addition' in the search text." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Shows operations on Series involving subtraction ('difference between...'), which helps confirm the '-' operator's usage in a pandas context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "The structural similarity is so high that this single snippet is likely enough for a student to guess the correct syntax." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets provide the identical syntactical pattern (df['C'] = df['A'] + df['B']). Translating 'sum' to 'difference' by changing the operator is a natural logical step even for non-programmers.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover vectorized addition perfectly, but do not explicitly show vectorized subtraction.", + "missing_concepts": [ + "Explicit vectorized subtraction syntax" + ], + "proposed_fix": "Add a snippet or modify an existing one to show that subtraction (-) works the same way as addition (+) in Pandas column operations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating element-wise subtraction: df['diff'] = df['X'] - df['Y'].", + "why_helpful": "It removes the slight leap of faith required to assume '-' works exactly like '+'.", + "why_maybe_unnecessary": "The 'sum' example is already extremely suggestive of the correct answer.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:00:50Z" + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q07", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q07", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-3", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 8.7 4.6 9.5 7.0\n2 7.3 1.5 6.3 7.1\n3 4.3 9.0 2.9 3.3\n4 4.8 2.5 5.1 3.0\n5 1.6 1.4 6.7 3.5\n6 2.4 3.7 7.6 1.3\n\nSuppose that you'd like to create a new Series that only contains those elements of column \"D\" of df that are smaller than 5.0. So the Series should look like this, when printed:\n\n3 3.3\n4 3.0\n5 3.5\n6 1.3\nName: D, dtype: float64\n\nWhich of the following code lines will not achieve what you want?", + "options": { + "a": "df.loc[2:6, df.columns[-1]]", + "b": "df.loc[df[\"D\"] < 5, \"D\"]", + "c": "df.loc[3:6, \"D\"]", + "d": "df.iloc[2:6, 3]" + }, + "correct": "a", + "explanation": "Option A slices rows 2 through 6 from the last column but does not filter out values that are 5.0 or larger, so it includes values that should not be in the result.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is a parallel version of the same question from a different exam year, providing a direct example of DataFrame selection and filtering logic which helps the student identify the pattern." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Directly matches the question structure and topic of pandas DataFrame selection." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a boolean mask for index selection and explains 'loc' logic, which is essential for understanding option B." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides additional context on pandas Series operations and structure, reinforcing how pandas handles numeric data." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides the most direct structural comparison for the student." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Introduces the concept of boolean masks used in the filtering logic of the question." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets provide parallel examples, a student with zero Python knowledge would struggle to distinguish between .loc (inclusive of end label) and .iloc (exclusive of end position) without a snippet that explicitly defines those mechanics. They might guess based on the 'Trial' exam snippet, but the technical 'why' is missing.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a clear explanation of the difference between label-based (.loc) and integer-position-based (.iloc) indexing, specifically regarding the inclusivity of the stop index.", + "missing_concepts": [ + "Difference between .loc (label-based, inclusive) and .iloc (position-based, exclusive)", + "How integer-based labels in .loc behave similarly to/differently from slicing", + "Explicit definition of boolean indexing (e.g., df[df['D'] < 5])" + ], + "proposed_fix": "Add a summary or 'cheat-sheet' style snippet that explicitly contrasts .loc, .iloc, and boolean masks with examples." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a conceptual snippet titled 'Pandas Selection Rules' that explains: 1. .loc[start:stop] is label-based and INCLUDES stop. 2. .iloc[start:stop] is zero-indexed position-based and EXCLUDES stop. 3. Boolean masks return only rows where the condition is True.", + "why_helpful": "This provides the 'rules of the game' that allow a student to logically deduce why Option A includes row 2 (label 2) while Option D starts at row 3 (position 2).", + "why_maybe_unnecessary": "If the student finds the full solution in the expanded 'Trial' exam snippet (item 6), they might just memorize the answer pattern.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:43:41Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q08", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q08", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-4", + "question": "You have two DataFrames: df1 and df2. They look like this when printed:\n\nprint(df1)\n\n Age Height Female City Language\n0 23 167 True Berlin German\n1 36 175 True Frankfurt German\n2 17 182 False Antwerpen Dutch\n3 25 177 True Eindhoven Dutch\n4 36 178 False Lyon French\n5 52 185 False Basel German\n6 46 168 True Innsbruck German\n\nprint(df2)\n\n Age Height Female City Language\n5 52 185 False Basel German\n4 36 178 False Lyon French\n1 36 175 True Frankfurt German\n6 46 168 True Innsbruck German\n0 23 167 True Berlin German\n\nWhich of the following code segments could have created df2 from df1?", + "options": { + "a": "df1.loc[df1[\"Language\"].isin([\"French\", \"German\"])].sort_values(\"Height\", ascending=False)", + "b": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_values(\"Age\", ascending=False)", + "c": "df1.loc[~df1[\"Language\"].isin([\"Dutch\"]), [\"Age\", \"Height\", \"City\", \"Language\"]].sort_index(ascending=False)", + "d": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_index(axis=1)" + }, + "correct": "a", + "explanation": "Option A filters out the Dutch rows and then sorts the remaining rows by Height in descending order, matching df2 exactly.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "It identifies the topic of 'Inspecting and Selecting Data' in Pandas, which is the core of the question, although the snippet content itself is truncated and does not provide the syntax rules." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Contextualizes Pandas selection tasks." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic Pandas DataFrame syntax (column creation/vectorization), which helps a student recognize the library structure." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Reinforces the concept of working with named columns in a DataFrame." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Closest match for the 'Selecting Data' theme." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the syntax for filtering (isin, !=, ~) or sorting (sort_values) in Pandas. A student with zero Python knowledge would not know what 'isin' does or how 'ascending=False' affects the result based on the provided candidates.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide zero explanation for Pandas-specific method syntax required to evaluate the options.", + "missing_concepts": [ + "pandas.DataFrame.sort_values(by, ascending)", + "pandas.Series.isin(list)", + "Boolean indexing/filtering with .loc", + "The negation operator (~) in Pandas boolean masks" + ], + "proposed_fix": "Add a summary snippet for Week 5 Pandas operations covering filtering (isin, comparisons) and sorting (sort_values)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas Filtering and Sorting. Content: Use df.loc[condition] to filter rows. Conditions: df['col'] == 'val', df['col'].isin(['a', 'b']), or ~ (not). Use df.sort_values('col', ascending=False) to sort by a column in descending order.", + "why_helpful": "It directly explains the functions used in the exam question options (isin, sort_values, ascending).", + "why_maybe_unnecessary": "If this information is expected to be in a lecture-based summary snippet that was simply not included in this search batch.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:43:58Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q09", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q09", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-1", + "question": "You have a list of mountain peaks and their heights in meters, all formatted as \"[PEAK NAME]: [HEIGHT]m\". For example, a few elements of the list are:\n\"Denali: 6,190m\", \"Aconcagua: 6,961m\", \"Kilimanjaro: 5,895m\", ...\n\nAs you can see, the comma (\",\") is used as a thousand separator in the height. The list is called mountains.\n\nYou'd like to create a dictionary called peaks from the mountains list. The peak names would be the keys, and the corresponding integer values. Continuing the example above, a few key-value pairs of the peaks dictionary should be:\n\"Denali\": 6190, \"Aconcagua\": 6961, \"Kilimanjaro\": 5895, ...\n\nWhich of the following two code segments achieves what you want?", + "options": { + "a": "peaks = {peak.split(\":\")[0]: int(peak.split(\": \")[1][:-1].replace(\",\", \"\")) for peak in mountains}", + "b": "names = [peak.split(\":\")[0] for peak in mountains]\nheights = [int(peak.split(\": \")[1].replace(\",\", \"\").replace(\"m\", \"\")) for peak in mountains]\npeaks = dict(zip(names, heights))", + "c": "Both code segments above achieve the intended outcome.", + "d": "Neither of the two code segments above achieves the intended outcome." + }, + "correct": "c", + "explanation": "Both solutions strip off the trailing m, remove the thousands separator, convert the height to an integer, and pair each mountain name with its numeric height.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Directly addresses creating a dictionary (word_lengths) from a list of strings (words), which is the primary task of the exam question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Covers the pattern of mapping a list to a dictionary with transformed keys/values." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Relevant to Option B as it involves creating a dictionary from two separate lists (names and ages)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Demonstrates string manipulation (splitting, replacing characters) which is crucial for cleaning the height data in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Establishes the dictionary-from-list pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides context for multi-list dictionary creation (zip-like behavior)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Shows string cleaning methods (replace)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Shows complex string extraction (top-level domain from URL), similar to extracting peak names and heights." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While existing snippets cover dictionary creation from lists and string manipulation separately, none explicitly show the 'dictionary comprehension' syntax {k: v for ...} or the 'dict(zip(...))' pattern in a single clear example that a novice could map 1:1 to the options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a clear example of dictionary comprehension syntax and the specific use of slicing [:-1] to remove a trailing character in a list context.", + "missing_concepts": [ + "dictionary comprehension syntax", + "zip() function for pairing lists", + "string slicing [:-1] for removing suffix", + "int() conversion within comprehensions" + ], + "proposed_fix": "Add a new snippet or edit an existing one to explicitly show a dictionary comprehension that includes a transformation (like int() or a string method)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: my_dict = {item.split(':')[0]: int(item.split(':')[1]) for item in my_list}", + "why_helpful": "This matches the exact syntax pattern used in Option A, allowing a student to recognize the structure.", + "why_maybe_unnecessary": "Some students might infer it from the 'word_lengths' question if the solution to that question used a comprehension.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: result = dict(zip(keys_list, values_list))", + "why_helpful": "Explicitly validates Option B's logic for students who have never seen zip().", + "why_maybe_unnecessary": "Option B is quite intuitive if 'zip' is assumed to 'pair things up', but for zero-knowledge, it needs proof.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:44:19Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q10", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q10", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-2", + "question": "You have a dictionary called grades, in which the keys are unique student ID's (as strings) and the corresponding values are each student's Python course grades (as floats).\n\nYou'd like to create another dictionary called grade_curve, in which the keys are the 18 possible Dutch course grades (1.0, 1.5, 2.0, ..., 10) as floats, and the corresponding (integer) values are the number of students in grades who have that particular grade.\n\nTake a look at the following code segment to create the grade_curve dictionary.\n\ndutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0,\n 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}\n\nDo you think this code segment will always work as intended? If not, then why not?", + "options": { + "a": "Yes, the code will always work as intended.", + "b": "The code will not work as intended if there are certain grades that no student has received. That will lead to an error in constructing the dictionary comprehension.", + "c": "The code will not work as intended, because the keys of the grades dictionary are not used in the list comprehension inside the sum function.", + "d": "The code will not work as intended, because including a list comprehension inside a dictionary comprehension will lead to a Python syntax error." + }, + "correct": "a", + "explanation": "The inner comparison list produces True and False values for every grade entry, and sum counts the matches, including zero when no student received that grade.", + "code_context": "dutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet describes creating a 'grade_counts' dictionary to count student frequencies per grade, which is the exact logical goal of the exam question, though it doesn't show the inner boolean sum implementation." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Directly relates to the problem domain of counting student grades in a dictionary format." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Confirms the syntax and validity of using dictionary comprehensions to map keys to computed values." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides another clear example of a dictionary comprehension creating mapping between a source list and a calculated property." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Establishes the intended outcome (frequency mapping)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Establishes dictionary comprehension syntax." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Mentions the 'sum' function used on values, confirming it as a valid built-in for numeric totals." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets verify the outer structure (dictionary comprehension) and the goal (counting grades), but no snippet explains that 'sum' can process a list of booleans (True/False) by treating them as 1 and 0. A student with zero knowledge might still doubt if sum([True, False]) is valid.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main conceptual hurdle is the implicit conversion of Booleans to integers during a sum operation, and the behavior of an empty match (summing all False values).", + "missing_concepts": [ + "Boolean to Integer coercion (True=1, False=0)", + "Summation of a boolean list", + "List comprehension producing booleans via equality checks" + ], + "proposed_fix": "Add a snippet or detail explaining how boolean conditions like 'x == y' inside a list comprehension interact with the sum() function." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: count = sum([val == target for val in collection]). Show that this results in an integer, even if the count is zero.", + "why_helpful": "This is the core 'trick' of the exam question. Without seeing that sum handles booleans, a student might incorrectly choose options B or D.", + "why_maybe_unnecessary": "The student might infer it if they see 'grade_counts' examples that work, but it's a leap for a 'zero knowledge' persona.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:44:39Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q11", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q11", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-1", + "question": "What does the following code segment print to the screen?\n\nfrom datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "options": { + "a": "26-03-2020", + "b": "04-24-2020", + "c": "15-04-2020", + "d": "05-14-2020" + }, + "correct": "a", + "explanation": "The string is parsed as 5 April 2020 using month.day.year format, and subtracting 10 days yields 26 March 2020, which is then formatted as day-month-year.", + "code_context": "from datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-parse", + "rationale": "Provides a clear example of `strptime` where the student can map the input string '2024-05-20' to the format codes '%Y-%m-%d', allowing them to infer that %m is month and %d is day." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-parse", + "rationale": "Shows how to parse strings and allows mapping of specific format codes (%m, %d, %Y) to date components." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Explains that adding a `timedelta` to a `datetime` shifts the date, which is necessary for the `date + timedelta(days=-10)` calculation." + }, + { + "item_id": "ks-755c23c4be", + "rationale": "Explicitly defines format codes like %m for month and %Y for year, and explains the purpose of `strftime`." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-parse", + "rationale": "Essential for understanding `strptime` and inferring format codes." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Essential for understanding date arithmetic with `timedelta`." + }, + { + "item_id": "ks-755c23c4be", + "rationale": "Essential for understanding `strftime` and confirming month/year codes." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of snippets allows a student to decode the format string in `strptime` (04 is month, 05 is day), understand that adding a negative timedelta subtracts days, and finally format the result back into a string using the same codes.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are sufficient because they provide both explicit definitions and enough example context to infer the meaning of the format codes and the behavior of the arithmetic.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:44:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q12", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q12", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-2", + "question": "Suppose you have the following definition for a Meeting class, which records basic information about meetings in a calendar application.\n\nYou would like to add a method called lunch_meeting to this class, which returns a boolean value indicating whether there is any overlap between the official lunchtime (12:30 - 13:00) and the time of the meeting.\n\nFor example, if you construct a Meeting object as:\nmy_meeting = Meeting('Ask for salary raise', \"25-05-2022\", start_time='12:00', length=45)\nthen the method call:\nmy_meeting.lunch_meeting()\nshould return the boolean value True.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = lunch_start + timedelta(minutes=30)\n return self.start < lunch_end and self.end > lunch_start", + "b": "def lunch_meeting(self):\n return self.start < \"13:00\" and self.end > \"12:30\"", + "c": "def lunch_meeting(self):\n return start_time <= \"13:00\" and start_time + length > \"12:30\"", + "d": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = datetime(self.date.year, self.date.month, self.date.day, 13, 0)\n return self.start >= lunch_end or self.end <= lunch_start" + }, + "correct": "a", + "explanation": "Option A constructs the lunch interval on the same date and uses the standard interval-overlap check. The other options compare datetimes to strings, reference names that are not in scope, or use the non-overlap condition instead.", + "code_context": "from datetime import datetime, timedelta\n\nclass Meeting:\n def __init__(self, topic, date, start_time=\"09:00\", length=30):\n self.topic = topic\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day,\n int(start_time.split(':')[0]), int(start_time.split(':')[1]))\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to define a method within a class that compares attributes using boolean logic, which is the structural requirement for the lunch_meeting method." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates method definition and attribute comparison logic (higher score and more reviews)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows basic class attribute initialization, helping a beginner understand what 'self.date' or 'self.start' represents." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Illustrates calling methods on an object instance, which helps clarify the 'my_meeting.lunch_meeting()' context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Method syntax and comparison logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Class/Attribute structure." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the available snippets mention the 'datetime' or 'timedelta' modules. A student with zero knowledge would not know how to construct a datetime object, that you can't compare a datetime object to a string (Option B/C), or the syntax for adding time using timedelta.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The provided snippets focus on OOP basics and Pandas, entirely missing the 'datetime' module which is central to the question.", + "missing_concepts": [ + "datetime.datetime constructor syntax", + "datetime.timedelta usage for time arithmetic", + "Comparison rules between datetime objects and strings", + "Interval overlap logic (A < End2 and B > Start2)" + ], + "proposed_fix": "Add a summary snippet or an exam question snippet that specifically covers the datetime library, showing object creation and timedelta addition." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Topic Detail' or 'Cheat Sheet' item for Week 8 (Datetime) covering: 1. datetime(year, month, day, hour, minute) 2. timedelta(minutes=N) 3. Comparing datetimes using <, >, ==.", + "why_helpful": "This would give the student the specific syntax needed to evaluate Options A and D, and recognize that Option B/C are invalid comparisons.", + "why_maybe_unnecessary": "Only unnecessary if the student is expected to infer library usage from the provided 'code_context' in the question, but 'zero knowledge' implies they need a reference.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:45:33Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q13", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q13", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Basic logic 2", + "question": "Suppose you have a variable x which contains a list of tuples, as follows:\n\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nChoose the correct output for the following line of code.\n\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "options": { + "a": "True", + "b": "False", + "c": "NameError", + "d": "SyntaxError" + }, + "correct": "a", + "explanation": "The left-hand side is 2 * 3 = 6 and the right-hand side is 8 - 2 = 6, so the comparison evaluates to True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This snippet uses the exact same list 'x' and explains the logic for a very similar boolean comparison, showing how specific indices map to numerical values (e.g., 2 * 3 == 6)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Directly matches the data structure 'x' and provides evaluation examples for index-based arithmetic." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Provides redundant confirmation of the evaluation logic for the same variable 'x' and tuple-in-list structure." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions string/list indexing and slicing which helps a student understand the concept of 0-based indexing used in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Provides the exact list content and a mapped numerical result for a nearly identical expression." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets essentially contain the answer key for a previous version of this exact question, mapping the indexing operations to the numerical values (2, 3, 6, etc.) needed to solve it.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the student can 'match' the patterns from the snippets to get the answer, there is no explicit rule provided for negative indexing (e.g., -1 is the last item).", + "missing_concepts": [ + "negative indexing rules", + "nested indexing (list of tuples) mechanics" + ], + "proposed_fix": "Add a snippet from a lecture or guide that explicitly defines that x[-1] refers to the last element and x[0] refers to the first." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining Python's negative indexing (e.g., index -1 is the last item, -2 is second to last) and nested indexing (e.g., x[0][1] accesses the second element of the first item).", + "why_helpful": "It would move the student from 'pattern matching' against old exams to actually understanding the logic required to solve the indexing math independently.", + "why_maybe_unnecessary": "The existing exam snippets are so similar that the student will likely find the answer by visual comparison alone.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:45:52Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q14", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q14", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Basic loop 2", + "question": "Which of the following code segments will print every even number between 0 and 20 (including 0 and 20) to the screen?", + "options": { + "a": "for i in range(0, 20):\n if i % 2 == 0:\n print(i)", + "b": "i = 0\nwhile i <= 20:\n if i % 2 == 0:\n print(i)\n i += 1", + "c": "for i in list(range(0, 20)):\n print(i if i % 2 == 0 else None)", + "d": "i = 0\nwhile i < 21:\n print(i)\n i += 1" + }, + "correct": "b", + "explanation": "Option B checks every integer from 0 through 20 inclusive and prints only the even ones. Option A never reaches 20, option C also prints None for odd numbers, and option D prints every number.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "This snippet demonstrates the modulo operator (% 2 == 0) for checking parity and introduces the range function, both of which are central to identifying the correct code segment in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Shows the syntax for checking if a number is even (i % 2 == 0) and how the range function is structured." + }, + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Explicitly confirms that specific programs (likely using modulo) correctly identify odd vs even numbers, reinforcing the concept needed for the 'if i % 2 == 0' filter." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "The explanation clearly states that 'while i < 11' runs from 1 to 10, which helps a student understand the exclusive boundary logic required to evaluate 'range(0, 20)' and 'while i < 21'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Introduces modulo parity checks and the range function." + }, + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Validates the use of the modulo operator for even/odd detection." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Explains exclusive loop boundaries (i < 11 means up to 10)." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover parity checking and the 'exclusive' nature of loop boundaries (i < 11). However, they don't explicitly state that range(0, 20) also follows this exclusive stop rule, requiring the student to make an inferential leap from while-loop boundaries to range-function boundaries.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main missing piece is a clear explanation of how range(start, stop) behaves regarding the upper bound.", + "missing_concepts": [ + "Explicit definition of range(start, stop) upper-bound exclusivity.", + "Direct comparison between i <= 20 (inclusive) and i < 21 (exclusive)." + ], + "proposed_fix": "Add a snippet or detail that explains the range(start, stop) parameters clearly, specifically noting that 'stop' is not included." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining the range() function: range(0, 10) produces numbers 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The number 10 is not included.", + "why_helpful": "This directly addresses the confusion between range(0, 20) and range(0, 21) which is the primary distractor in options A and C.", + "why_maybe_unnecessary": "Students might infer it from the 'while i < 11' explanation, but it is a risky assumption for a total beginner.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:46:16Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q15", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q15", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Basic scope 2", + "question": "Choose the correct statement about the program below:", + "options": { + "a": "a is a global variable. b, c, d are local variables.", + "b": "a, b are global variables. c, d are local variables.", + "c": "a, b, c, d are global variables.", + "d": "a, c, d are global variables. b is a local variable." + }, + "correct": "a", + "explanation": "`a` is defined at module level, so it is global. `b` is local to `outer`, and `c` and `d` are local to `inner`.", + "code_context": "a = 1\ndef outer(b):\n b = 2\n def inner(c):\n d = 3\n return a + c + d\n return inner(4) + b" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Explicitly defines global names (outside functions) and local names (parameters + assignments inside functions), which allows direct categorization of a, b, c, and d." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the foundational rules for distinguishing global vs local scope based on definition location and parameters." + }, + { + "item_id": "manual-scope-local-name", + "rationale": "Reinforces that parameter names (like b and c) are local and do not exist outside the function body." + }, + { + "item_id": "ks-f069ee6a0b", + "rationale": "Explains that functions can be defined inside other functions, validating the 'inner' and 'outer' structure shown in the code." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Covers the rules for a (outside), b/c (parameters), and d (assignment inside)." + }, + { + "item_id": "ks-f069ee6a0b", + "rationale": "Clarifies the nested function structure used in the code context." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "ks-2a6510492d provides precise definitions for both global variables (defined outside) and local variables (parameters or assigned inside). A student can apply these rules to identify 'a' as global and 'b, c, d' as local without needing prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective. The only minor ambiguity for a complete novice might be whether a variable local to an 'inner' function counts as 'local' in a general sense, but the definitions provided are broad enough to cover this.", + "missing_concepts": [ + "Explicit confirmation that 'local' as a general term includes variables in nested scopes (non-local/closure variables)." + ], + "proposed_fix": "Add a note to the 'Global and local scope' lecture snippet stating that any variable defined inside a function (regardless of nesting level) is considered local relative to the global scope." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-2a6510492d", + "proposal": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). This applies to all functions, including those nested inside others. Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates).", + "why_helpful": "It explicitly bridges the gap between simple local variables and variables defined in nested function structures, which is the core of this specific exam question.", + "why_maybe_unnecessary": "The current definition 'defined inside a function' already technically covers nested functions, and the exam options don't require distinguishing between 'local' and 'non-local'.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:46:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q16", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q16", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-1", + "question": "You have to write a function called main, which takes a list of unique integers as an argument and returns a dictionary.\n\nThe output dictionary should consist of all key-value pairs for which the key is an element of the input list and the value is the next element of the input list. When there is no \"next element\" any more, leave the key-value pair out of the dictionary.\n\nFor example, if your function is called as:\nmain([1, 3, 2, 4])\nthen it should return the dictionary:\n{1: 3, 3: 2, 2: 4}\n\nWhich of the following programs work(s) according to the requirements?", + "options": { + "a": "def main(l1):\n result = {}\n index = 0\n while True:\n index = index + 1\n if index >= len(l1):\n break\n else:\n result[l1[index]] = l1[index + 1]\n return result", + "b": "def main(l1):\n result = {}\n for index, value in zip(l1[:-1], l1[1:]):\n result[index] = value\n return result", + "c": "Both programs work as required", + "d": "Neither of the two programs works as required" + }, + "correct": "b", + "explanation": "Option B correctly zips each element with the following element and builds the required dictionary. Option A starts at index 1 and eventually tries to access past the end of the list.", + "code_context": "main([1, 3, 2, 4])\n# should return {1: 3, 3: 2, 2: 4}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "It demonstrates the fundamental pattern of initializing an empty dictionary (`y = {}`) and populating it within a loop, which is the basic structure used in both code options." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows dictionary initialization and population logic which is central to the question's code structure." + }, + { + "item_id": "aiq-5", + "rationale": "Shows a function taking a list and returning a dictionary populated with specific keys and values derived from that list." + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Discusses returning pairs of numbers from a list, which conceptually aligns with the 'key-next element' pairing requirement." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Basic dictionary/loop pattern." + }, + { + "item_id": "aiq-5", + "rationale": "Function returning a dictionary from a list input." + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Context for pairing logic." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Reinforces dictionary key-value mapping concepts." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the available snippets explain list slicing (e.g., `l1[:-1]`) or the `zip()` function, which are essential to understand why Option B works. Furthermore, there are no examples of 'while' loops with index manipulation that would help a student realize why Option A fails (incorrect starting index and boundary risk).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets cover basic dictionary creation but lack technical details on sequence iteration and pairing.", + "missing_concepts": [ + "zip() function for parallel iteration", + "list slicing (e.g., list[:-1] and list[1:])", + "while loop indexing and off-by-one errors" + ], + "proposed_fix": "Add a snippet or AI-generated example specifically demonstrating how to pair adjacent elements in a list using both zip/slicing and indexed loops." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Idioms' snippet: 'To pair adjacent elements in a list `L`, use `zip(L[:-1], L[1:])`. This creates pairs of (current, next). Alternatively, an indexed loop would use `range(len(L)-1)` to avoid an index-out-of-bounds error when accessing `L[i+1]`.'", + "why_helpful": "It directly explains the syntax used in the correct answer (Option B) and clarifies the boundary conditions that make Option A incorrect.", + "why_maybe_unnecessary": "If the course focuses more on manual indexing than built-in idioms, but given it appears on the exam, it is necessary.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:46:56Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q17", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q17", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-2", + "question": "What will be printed by the following program?", + "options": { + "a": "True", + "b": "False", + "c": "An error message", + "d": "None" + }, + "correct": "a", + "explanation": "Dictionary equality compares key-value contents rather than insertion order. Since both dictionaries contain the same pairs, the comparison prints True.", + "code_context": "d1 = {1: 5, 4: 6}\nd2 = {4: 6, 1: 5}\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet explicitly explains how the equality operator (==) works in Python, providing concrete examples of True/False results for comparisons, which helps a student understand the mechanism being tested." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Establishes the behavior of the == operator for different types and boolean evaluation." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the syntax for a dictionary with integer keys and values, similar to the question's context." + }, + { + "item_id": "aiq-3", + "rationale": "Provides a trace of dictionary operations, helping the student recognize dictionary structure and key-value relationships." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Teaches equality operator behavior." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows dictionary key-value pair syntax." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets explain the '==' operator and show dictionary syntax, none of the provided materials explain that dictionaries are unordered collections where equality is based on content rather than insertion order. A student with zero knowledge might incorrectly assume order matters (like in a list).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing the specific rule that Python dictionaries compare equal if they have the same key-value pairs, regardless of order.", + "missing_concepts": [ + "Dictionary equality logic (content vs. order)", + "Unordered nature of dictionary comparisons" + ], + "proposed_fix": "Add an AI-generated question or a lecture snippet that explicitly compares two dictionaries with identical content but different key-value ordering." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'In Python, two dictionaries are considered equal (==) if they contain the same set of key-value pairs. The order in which the pairs were added does not affect equality. Example: {1: 'a', 2: 'b'} == {2: 'b', 1: 'a'} is True.'", + "why_helpful": "Directly addresses the core concept of the exam question which is currently completely unrepresented in the available snippets.", + "why_maybe_unnecessary": "Only unnecessary if we want students to guess based on general intuition that 'content is what matters', but that is risky for an exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:47:13Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q18", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q18", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-3", + "question": "d1 = {1: 2, 2: 1}\n\nThe following code segments all print exactly the same output, except for one. Which one?", + "options": { + "a": "result = 1\nfor x in d1.values():\n result *= x\nprint(result)", + "b": "result = -1\nfor x in d1.keys():\n result += d1[x]\nprint(result)", + "c": "result = 4\nfor x in d1.items():\n result = result // x[1]\nprint(result)", + "d": "result = -4\nfor x in d1:\n result /= d1[x]\nprint(result)" + }, + "correct": "d", + "explanation": "A, B, and C all print 2. Option D uses true division starting from -4, so it prints -2.0 instead, making it the odd one out.", + "code_context": "d1 = {1: 2, 2: 1}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "This snippet explicitly explains that iterating directly over a dictionary (as seen in option D) only yields keys, which is the most critical conceptual hurdle for this specific question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Clarifies that direct dictionary iteration (for x in d1) yields keys, aiding the evaluation of option D." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Introduces the .values() and .keys() methods, which are central to options A and B." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates accessing dictionary values using specific keys, which is necessary for options B and D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Covers direct iteration logic." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Covers .keys() and .values() methods." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Covers value retrieval by key." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover dictionary iteration methods and key-based access, there is no information regarding the .items() method, how to index into the resulting tuples (x[1]), or the distinction between floor division (//) and true division (/). A student would likely struggle to calculate the results for options C and D accurately.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gaps are the lack of information on the .items() method and the behavioral difference between the two types of division operators in Python.", + "missing_concepts": [ + ".items() method return format (list of tuples)", + "Tuple indexing (e.g., x[1])", + "Floor division (//) vs True division (/)" + ], + "proposed_fix": "Add a snippet or detail card that explains the .items() method and provides a comparison of division operators, including their effect on resulting data types (integer vs. float)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating dictionary iteration using .items() (e.g., 'for k, v in d.items()') and clarifying that 'for x in d.items()' makes 'x' a tuple where 'x[1]' is the value. Also include a clear distinction between // (integer/floor division) and / (true division).", + "why_helpful": "This would directly enable the student to solve option C (understanding items and indexing) and D (recognizing why the division results in a different value/type).", + "why_maybe_unnecessary": "If the student can guess that .items() provides both key and value and that x[1] follows standard indexing, but the division distinction is rarely intuitive to non-programmers.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:47:44Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q19", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q19", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-1", + "question": "Suppose that you have a string called s1, which contains several letters. The letter \"x\" and the letter \"y\" occur exactly once in the string, and \"x\" always precedes \"y\".\n\nYou'd like to print out a string that looks just like s1, except that the letters \"x\" and \"y\" should be swapped.\n\nFor example, if:\ns1 = \"axbyc\"\nthen you'd like to print:\naybxc\n\nReminder: The replace string method has a third argument, which allows you to specify the maximum number of replacements you want to make, counting from left to right.", + "options": { + "a": "s1 = s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "b": "s1 = s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)", + "c": "s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "d": "s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)" + }, + "correct": "b", + "explanation": "Option B first changes the single y to x, then changes the first x from left to right back to y, which swaps the two letters. Options C and D do not assign the new string back to s1, and A changes the first replacement back incorrectly.", + "code_context": "s1 = \"axbyc\"\n# desired printed result: aybxc" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "While it focuses on pandas .map() and .split(), it is the only snippet categorized under 'String Fundamentals' that mentions applying transformations to string values, though it lacks the critical explanation of .replace()." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides the closest context for string manipulation logic, even if the specific methods differ." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions formatting a string by removing characters (dashes), which implies string cleaning/replacement logic, though the code is not visible." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Shows a problem involving string parsing (TLD extraction), reinforcing that strings are handled through specific method calls." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Establishes the concept of transforming string data." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain the 'replace' method, its optional 'count' argument, or the fundamental concept of string immutability (which explains why s1 = s1.replace... is required). A student with zero knowledge could not distinguish between the options based on this data.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus on high-level data structures (DataFrames, Lists of Dictionaries) or specific complex functions (anagrams, TLDs) rather than basic string methods and object immutability.", + "missing_concepts": [ + "String immutability (methods return a new string; original is unchanged)", + "The .replace(old, new, count) method syntax and behavior", + "Variable reassignment logic for string updates" + ], + "proposed_fix": "Add a foundational snippet covering basic string methods (replace, strip, split) that explicitly mentions they return new objects and explains the optional 'maxreplace' argument." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Methods and Immutability. Content: Strings in Python are immutable; methods like .replace() return a NEW string rather than modifying the original. Usage: s.replace('old', 'new', 1) replaces only the first occurrence.", + "why_helpful": "This directly addresses the mechanics required to solve the question: the need for assignment (s1 = ...) and the effect of the third argument.", + "why_maybe_unnecessary": "If the course assumes students already know basic string manipulation from earlier weeks, but the prompt specifies 'zero prior knowledge'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:04Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q20", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q20", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-2", + "question": "Take a look at the following function definition.\n\nWhat will be returned by the following function call:\nglue(a='e', b='d')", + "options": { + "a": "ab", + "b": "cd", + "c": "ba", + "d": "dc" + }, + "correct": "c", + "explanation": "The function iterates over the keyword names in insertion order (`a`, then `b`) and prepends each key to the current result. Starting from the empty string, that produces `a`, then `ba`.", + "code_context": "def glue(**kwargs):\n result = ''\n for el in kwargs.keys():\n result = el + result\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Explains that a function accepting a flexible number of keyword arguments (which corresponds to **kwargs in the code) uses those arguments like a collection, helping the student identify the source of 'kwargs'." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Identifies that keyword arguments passed to a function are handled as a group (the **kwargs pattern)." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows a 'for key in x' loop structure where 'key' is used to iterate through a collection, which parallels the loop in the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Shows string manipulation logic in functions, which is the secondary operation in the question (concatenating strings)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Connects the function call glue(a='e', b='d') to the concept of keyword arguments." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Demonstrates the syntax for iterating through a set of keys in a dictionary-like object." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "medium", + "rationale": "While the snippets explain what keyword arguments are and how loops work, they do not explicitly state that 'kwargs.keys()' returns the parameter names ('a', 'b') as strings. A zero-knowledge student might reasonably assume 'el' refers to the values ('e', 'd') or the combined pairs without a specific reference to the .keys() method.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no snippet that explains the mapping between keyword argument names (the keys) and their values within the **kwargs dictionary, specifically how .keys() behaves.", + "missing_concepts": [ + "**kwargs keys as parameter name strings", + "dict.keys() return values", + "string prepending order (el + result vs result + el)" + ], + "proposed_fix": "Add a snippet or AI common question that explicitly traces a function using **kwargs.keys() to show it yields the names of the arguments as strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Understanding **kwargs and .keys(). Code: def show_keys(**kwargs): return list(kwargs.keys()). Call: show_keys(first='val1', second='val2'). Output: ['first', 'second'].", + "why_helpful": "This would explicitly teach the student that the 'keys' in keyword arguments are the names used in the call, not the values assigned to them.", + "why_maybe_unnecessary": "One might argue that 'keys' is a semantically intuitive word, but in programming 'key' vs 'value' is a specific distinction that needs defining for a novice.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:22Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q21", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q21", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-3", + "question": "Take a look at the following function definition.\n\nWhat will be printed to the screen by the following code?\nprint(tester())", + "options": { + "a": "1", + "b": "-1", + "c": "0", + "d": "None" + }, + "correct": "a", + "explanation": "The default argument is `0`, which satisfies the non-negative condition, so the function returns `1` and `print` outputs `1`.", + "code_context": "def tester(i1 = 0):\n if i1 >= 0:\n return 1\n\n if i1 < 0:\n return -1" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explicitly demonstrates function definitions with multiple default arguments and shows the results of calling the function when some arguments are omitted." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Covers the core mechanic of default arguments (num2=10, num3=20) being used when not provided in the call." + }, + { + "item_id": "manual-print-vs-return", + "rationale": "Explains the fundamental flow: a function returns a value to the caller, which can then be displayed using the print() function." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Provides a direct example of a function called with one argument where the second defaults (y=11), matching the structure of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Teaches default argument behavior." + }, + { + "item_id": "manual-print-vs-return", + "rationale": "Teaches how 'return' values interact with 'print()'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets clearly explain that if an argument is not provided (tester()), the default value (i1=0) is used, and that the value 'returned' by the function is what 'print' displays.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover the logic well. A minor gap is the explicit definition of comparison operators like '>=' for complete beginners, though they are mathematically intuitive.", + "missing_concepts": [ + "Comparison operator syntax (>=, <)" + ], + "proposed_fix": "Add a small reference snippet for common comparison operators." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: Comparison Operators. x >= y means 'x is greater than or equal to y'. x < y means 'x is less than y'. Example: 0 >= 0 is True.", + "why_helpful": "Ensures a student with zero coding background doesn't second-guess the meaning of the mathematical symbols in Python.", + "why_maybe_unnecessary": "Most students recognize >= and < from basic math.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q22", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q22", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "List lambda 2", + "question": "Assume that you have a variable called x, which contains a list of integers.\n\nWhich of the following code segments will create another list that has every element of x multiplied by 2?\n\nFor example, if\nx = [1, 2, 3, 4, 5]\nthen which of the following code segments will result in the list:\n[2, 4, 6, 8, 10]", + "options": { + "a": "list(map(lambda i : i * 2, x))", + "b": "[(lambda i : i * 2)(item) for item in x]", + "c": "y = lambda i : i * 2\n[y(i) for i in x]", + "d": "All three code segments would work as intended" + }, + "correct": "d", + "explanation": "Each option constructs the doubled list correctly: `map` with a lambda, an immediately called lambda inside a list comprehension, and a named lambda used inside a list comprehension all apply `i * 2` to every element of `x`.", + "code_context": "x = [1, 2, 3, 4, 5]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "This snippet asks how to create a list of squared values from an existing list 'x', which is structurally identical to the target question's goal of doubling values. It likely demonstrates the list comprehension or mapping pattern needed." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Provides the closest structural analogy for transforming a list of integers into a new list of transformed integers." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explicitly mentions the .map() method and its purpose in applying a function to elements, helping to validate Option A." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Establishes the pattern for list-wide operations." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces the concept of mapping a function over a collection." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets hint at list transformations and the map() function, none of the available snippets define or explain the 'lambda' keyword or the specific syntax of immediately invoked lambdas within list comprehensions. A student with zero knowledge would not be able to confirm if 'lambda i : i * 2' is correct syntax.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of 'lambda' syntax explanation in the recommended snippets.", + "missing_concepts": [ + "Lambda function syntax (lambda arguments : expression)", + "Immediately Invoked Function Expressions (IIFE) in Python", + "Differences between named functions and lambdas in comprehensions" + ], + "proposed_fix": "Add a dedicated reference snippet or topic card covering 'Anonymous Functions (Lambda)' that shows its usage in map() and list comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a topic card titled 'Lambda Functions and List Mapping'. It should show: 1. `list(map(lambda x: x*2, my_list))`, 2. `[ (lambda x: x*2)(i) for i in my_list ]`, and 3. `f = lambda x: x*2; [f(i) for i in my_list]`.", + "why_helpful": "This would directly address all three options (a, b, and c) in the question, allowing a student to recognize the patterns as equivalent.", + "why_maybe_unnecessary": "Only unnecessary if the student is expected to already know basic functional programming concepts, but the prompt assumes zero knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:48:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q23", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q23", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "List logic 2", + "question": "Which of the following programs creates a new list y, in which the elements are those elements of list x that are equal to their indices?\nYou can assume x consists of unique integers.\n\nFor example, if:\nx = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\nthen the program should create a new list y such that:\ny = [0, 3, 6, 7, 8, 10]", + "options": { + "a": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(i)", + "b": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(j)", + "c": "y = [i for i in x if i == x.index(i)]", + "d": "All three programs would work as intended" + }, + "correct": "d", + "explanation": "In A and B, whenever `i == j`, appending either `i` or `j` gives the same value because the index equals the element. In C, `x.index(i)` returns the position of `i`, so the comprehension keeps exactly the elements equal to their indices. Therefore all three programs work.", + "code_context": "x = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\n# target result:\ny = [0, 3, 6, 7, 8, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This snippet involves converting a sequence to a list and relates to loop logic, which is the closest match to the list construction required in the question, although it does not explain enumerate or index." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides context on list creation and looping logic." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a 'boolean mask on the index', which introduces the concept of filtering a collection based on index positions, even though it is in a Pandas context." + }, + { + "item_id": "exam-midterm_2023-11-w3-higher-order-patterns", + "rationale": "Discusses functions that accept lists and return new modified lists, which aligns with the structural goal of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Essential for understanding basic list and loop interactions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Connects index-based filtering to result outcomes." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets explain the specific Python built-ins 'enumerate()' or 'list.index()', nor do they provide examples of list comprehension syntax. A student with zero knowledge would not be able to distinguish between using index 'i' vs value 'j' in the enumerate options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate pool lacks any explanation of the 'enumerate' function, the '.index()' method for lists, and the syntax/logic for list comprehensions.", + "missing_concepts": [ + "enumerate() function", + "list.index() method", + "List comprehension syntax" + ], + "proposed_fix": "Add a snippet from Week 2 or 3 course material that explicitly defines 'enumerate' and its return values (index, element), and another that demonstrates basic list comprehensions with an 'if' condition." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining 'enumerate(iterable)': 'The enumerate() function adds a counter to an iterable and returns it as an enumerate object. Example: for index, value in enumerate(['a', 'b']): print(index, value) outputs 0 a and 1 b.'", + "why_helpful": "Directly explains how variables 'i' and 'j' are populated in the loop options (a and b).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining list comprehensions: '[expression for item in list if condition] creates a new list by applying the expression to each item that meets the condition.'", + "why_helpful": "Enables the student to understand the syntax of Option C.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:49:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-solutions-for-python-programming-62oop21-q24", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q24", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "List loop 2", + "question": "Assume that you have a list called x, which is a list of multiple sub-lists containing integers.\n\nWhich of the following programs will create a new list y that is equal to the sub-list of x whose sum of elements is the highest?\n\nYou can assume that the sum of elements in each sub-list is a different number, so that there is only one that is the highest.\n\nFor example, if:\nx = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\nthen y should be:\ny = [8, 20, 300]", + "options": { + "a": "y = max(x)", + "b": "z = []\nfor i in x:\n z.append(sum(i))\ny = x[z.index(max(z))]", + "c": "x.sort()\ny = x[-1]", + "d": "y = [i for i in x if sum(i) == max(x)]" + }, + "correct": "b", + "explanation": "Option B computes the sum of each sub-list, finds the position of the largest sum, and then returns the corresponding original sub-list. The other options compare lists lexicographically or compare a numeric sum against `max(x)`, which is a list.", + "code_context": "x = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\n# target result:\ny = [8, 20, 300]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Shows the basic structure of iterating through a list 'x' and performing operations on its elements to create a new result, which is the core logic of the loop in Option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Demonstrates looping over a list 'x' to generate a new list of transformed values." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Mentions a function that 'sums even integers' in a list, introducing the 'sum()' concept which is critical for calculating sub-list totals." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Introduces list sorting and manipulation, which helps contrast with the lexicographical comparison mentioned in the explanation (Option C)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "rationale": "Basic list iteration pattern." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduction to 'sum()' behavior." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "General list behavior and comparison context." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows mapping elements from a list to another structure (dictionary), similar to how indices map 'z' to 'x'." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While iteration and summing are touched upon, no snippet explains the 'list.index()' method or the specific logic of finding the maximum value's position to retrieve an item from a parallel list. A student would struggle to identify Option B as correct without knowing how '.index()' and 'max()' interact.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets fail to cover list search methods and the pattern of index-based retrieval.", + "missing_concepts": [ + "list.index()", + "max() function on numeric lists", + "Parallel list indexing (using index of one list to access another)" + ], + "proposed_fix": "Add a snippet demonstrating how to find the index of a specific value (like the maximum) in one list and use it to retrieve data from a corresponding list." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'prices = [10, 50, 20]; max_price = max(prices); best_index = prices.index(max_price); items = [\"apple\", \"pear\", \"banana\"]; print(items[best_index])'", + "why_helpful": "This directly demonstrates the index-retrieval pattern used in the correct answer (Option B).", + "why_maybe_unnecessary": "If the student already understands that indices link related lists, they might guess it, but it's a specific technical hurdle.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:49:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-study-guide-trial-python-basics-2023.json b/data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-study-guide-trial-python-basics-2023.json new file mode 100644 index 0000000..0b0a29c --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round1/final-exam-study-guide-trial-python-basics-2023.json @@ -0,0 +1,2125 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q01", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q01", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_2", + "question": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\n- If they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\n- If they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?", + "options": { + "a": "if destination in europe:\n print('No passport needed. Bring your ID card.')\nelse:\n print('Please bring your passport.')", + "b": "if destination in europe:\n return 'No passport needed. Bring your ID card.'\nelif destination not in europe:\n return 'Please bring your passport.'", + "c": "for country in europe:\n if destination = country:\n print('No passport needed. Bring your ID card.')\n else:\n print('Please bring your passport.')", + "d": "for country in europe:\n if destination != country:\n return 'Please bring your passport.'\n else:\n return 'No passport needed. Bring your ID card.'" + }, + "correct": "a", + "explanation": "Option A directly checks whether destination is in the list of European countries and prints the correct message in each case. The other options either use the wrong control flow or invalid syntax.", + "code_context": "europe = [...]\ndestination = ..." + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination. You want to write a ", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "This snippet is a perfect contextual match as it contains the exact same question text and scenario, helping the student identify the problem as a known pattern even if it doesn't explicitly provide the code." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Matches the question scenario (Europe list and destination string) exactly." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Provides a reference for the 'Conditions' topic, which is the fundamental logic required (if/else)." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Covers loops and list processing, which helps a student understand why the 'for' loop approaches in options C and D are different from the simple membership check." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Provides the exact scenario context." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While one snippet matches the question text, none of the available snippets explain the syntax or behavior of the 'in' operator for list membership, nor do they clarify the distinction between 'print' and 'return' in this context. A student with zero knowledge would not know that 'destination in europe' is a valid Python expression.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide the scenario context but fail to explain the technical syntax required to solve it.", + "missing_concepts": [ + "Membership operator ('in') for checking if an item exists in a list", + "Basic if-else branching syntax", + "Difference between 'print()' and 'return' (especially outside of functions)" + ], + "proposed_fix": "Add a foundational 'Python Basics' snippet that demonstrates checking if a string is inside a list using 'if x in my_list:'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'List Membership and Branching' with search text: 'To check if a value exists in a list, use the \"in\" operator: if item in my_list:. Use \"else:\" to handle cases where it is not found.'", + "why_helpful": "This directly teaches the 'zero-knowledge' student the exact syntax needed to choose Option A over the incorrect loop or return-based options.", + "why_maybe_unnecessary": "If the student is expected to deduce syntax from other exam questions not listed here.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q02", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q02", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_3", + "question": "Calling the function func_10 will produce an error. Which line of the following code segment produces the error?", + "options": { + "a": "'var_2 = var_1 * var'\nThis line produces the error because func_2() was not called and assigning the value to var_1, thus var_1 was referenced before being defined.", + "b": "'var_1 = var * 2'\nThis line produces the error because Python is confused about which value var should have.", + "c": "'def func_2(var):'\nThis line produces the error because the name var is already used for the argument of func_1() and cannot be used again as the name of the argument for func_2().", + "d": "'return var_2'\nThis line produces the error because one function cannot return two outputs." + }, + "correct": "a", + "explanation": "The inner function func_2 is defined but never called, so var_1 is never assigned before the line var_2 = var_1 * var tries to use it.", + "code_context": "def func_1(var):\n def func_2(var):\n var_1 = var * 2\n return var_1\n var_2 = var_1 * var\n return var_2" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "This snippet is a near-identical match to the exam question, explicitly stating that var_1 is a local variable inside func_2 and that func_2 is never called, which directly explains the error in the provided code." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a direct parallel to the question and explains the specific error (local scope and uncalled function)." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the fundamental rules of local and global scope in Python, which is the core concept needed to understand why the variable is inaccessible." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Directly addresses the error in the code context." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the general rule for local scope names being 'Only known inside the function'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippet 'exam-Trial final...-2-w3-scope' contains the exact logic and explanation for this specific function-nesting error. A student can solve the question by pattern-matching the code structure and reading the snippet's explanation.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets are highly sufficient. The direct match snippet even accounts for the 'function never called' and 'local variable' nuances.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q03", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q03", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[str, int, NoneType, bool, float, str, dict]", + "b": "[str, int, NoneType, bool, float, bool, dict]", + "c": "[str, int, NoneType, bool, float, str, list]", + "d": "[str, float, NoneType, bool, int, str, dict]" + }, + "correct": "a", + "explanation": "The function appends the type of each element in the input list in order: string, integer, NoneType, boolean, float, string, and dictionary.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n list_2.append(type(item))\n return list_2\n\nmain(['abc', 0, None, True, 123.456, 'False', {}])" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What is the output of the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ], + "evidence_topics": [ + "Return Behavior" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet is a direct match for the question. It explicitly maps every element in the question's list ('abc', 0, None, True, 123.456, 'False', {}) to its corresponding Python type (str, int, NoneType, bool, float, str, dict)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Directly provides the answer and mapping for all types in the specific question." + }, + { + "item_id": "ks-cb3a9e3fd2", + "rationale": "Provides a clear reference for 'The 8 types to know' (int, float, str, bool, etc.) with syntax examples, which is fundamental for this topic." + }, + { + "item_id": "exam-extra_practice-11-w1-objects-and-names", + "rationale": "Shows a complex list with various types (string, nested list, tuple, dict, bool, float, int) and illustrates how to determine their types using indices." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Because this snippet is an exact duplicate of the exam question and includes a full explanation of the result, it is sufficient on its own." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior' contains the exact same code and input list, and provides a textual breakdown of every item's type, matching option 'a' perfectly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate snippets are highly effective because they include a direct match for the question. Even without the direct match, the combination of lecture notes on the '8 types' and other exam questions covering 'str vs bool' would allow a student to piece together the answer.", + "missing_concepts": [], + "proposed_fix": "No additions are strictly necessary, though ensuring the '8 types' snippet (ks-cb3a9e3fd2) is not truncated in the UI would be beneficial." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:39Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q04", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q04", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 1", + "question": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\n\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97", + "options": { + "a": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou'}", + "b": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou' if vowel in 'aeiou'}", + "c": "Both of the code segments work correctly.", + "d": "Neither of the code segments work correctly." + }, + "correct": "c", + "explanation": "Both comprehensions produce the same dictionary because the extra condition in option B is always true for characters drawn from 'aeiou'.", + "code_context": "print(vowels_ASCII)\n# expected: {'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values. The ASCII (American", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact text and logic of the exam question, making it the most direct reference for a student." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Identical question match, providing the specific scenario of vowels and ASCII values." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a secondary example of dictionary comprehension syntax ({key: value for ...}), reinforcing the pattern used in the correct answer." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Discusses creating a dictionary from two lists (names/ages) with conditions, which helps explain the 'if' clause logic in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Contains the specific problem statement and variables needed to identify the correct code structure." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question text and logic are present in the 'best_single_snippet'. A student can use pattern matching to identify 'vowels_ASCII' and the dictionary comprehension syntax.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets are sufficient because the exact question is mirrored in the source exam items.", + "missing_concepts": [], + "proposed_fix": "No fix needed; the coverage for this specific question is 100%." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:50:55Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q05", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q05", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 1", + "question": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = (goals1, goals2, goals3)", + "b": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = [goals1 + goals2 + goals3]", + "c": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = [goals1, goals2, goals3]", + "d": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = (goals1, goals2, goals3)" + }, + "correct": "a", + "explanation": "Option A uses enumerate with start=1 to create the correct match-number keys and stores each triple of goal counts as a tuple. The other options either use the wrong value shape or start indexing from 0.", + "code_context": "player1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\nprint(match_goals)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals score", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "This is an exact match for the question provided. It contains the identical scenario, variables (player goals), and target dictionary structure, making it the most direct reference for a student." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Direct duplicate of the exam question; provides immediate context and the correct logic pattern." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows the general pattern of creating a dictionary from a list and evaluating which code segment works as intended, which mirrors the multiple-choice format." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a dictionary where keys are integers starting from 1 (1 to 5), helping the student understand the 'match numbers starting from 1' requirement." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Provides the exact question and likely the solution/logic required for the player_goals scenario." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Confirms the expected output format for 1-based integer keys in a dictionary." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question being asked. Even without prior Python knowledge, a student can identify the matching variable names and logic structure from the provided reference.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the exact question, but they lack a generic explanation of the 'zip' and 'enumerate' functions which are the core technical components of the correct answer.", + "missing_concepts": [ + "zip() for parallel iteration of multiple lists", + "enumerate() with the start parameter (start=1)", + "tuple vs list notation in dictionary values" + ], + "proposed_fix": "Add a lecture-based or reference snippet that explicitly explains how to use enumerate(list, start=1) to create 1-indexed keys." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining 'Iteration with Counters and Multiple Lists'. Examples: enumerate(mylist, start=1) and zip(listA, listB).", + "why_helpful": "This would allow a student to solve the problem by understanding the syntax (zip and enumerate) rather than just relying on finding a duplicate question.", + "why_maybe_unnecessary": "Since the duplicate question already exists in the exam bank, a student using the cheat sheet specifically for this course would likely find the direct answer anyway.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:51:13Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q06", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q06", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 1", + "question": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?", + "options": { + "a": "sales_subset = [monthly_sales[key] for key in list(monthly_sales.keys())[:3]]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "b": "sales_subset = monthly_sales[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "c": "sales_subset = list(monthly_sales.items())[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "d": "sales_subset = monthly_sales['January':'March']\naverage_sales = sum(sales_subset.values()) / len(sales_subset)\nprint(average_sales)" + }, + "correct": "a", + "explanation": "Option A first collects the values for the first three keys into a list and then computes the average correctly. The other options attempt unsupported dictionary slicing or try to sum tuples instead of numeric values.", + "code_context": "monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You have the following dictionary that represents the monthly sales of a store: monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "This snippet is an exact match for the question scenario, providing the specific dictionary and the objective of calculating average sales for January-March." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Directly contains the question text and scenario." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a similar question structure (multiple choice options a-d) and mentions 'Option A' as a valid solution, reinforcing the pattern." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Shows the concept of summing values from a set of data, which is part of the required calculation in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Provides the exact context needed to identify the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the candidate snippet list. A student can match the 'monthly_sales' dictionary and 'average sales' goal to find the answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact question is present, the snippets do not explicitly explain *why* slicing a dictionary directly fails or that items() returns tuples. This makes answering other similar questions difficult without the exact match.", + "missing_concepts": [ + "Dictionary slicing limitations", + "Type of objects returned by dict.items() (tuples)", + "List comprehension with slicing on keys()" + ], + "proposed_fix": "Add a theoretical snippet explaining that dictionaries are unordered/unsliceable and that list(d.keys())[:n] is the standard way to get a slice of keys." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "proposal": "Ensure the full text including the correct code segment and the explanation (why direct slicing fails) is visible in the snippet search text.", + "why_helpful": "It would provide the 'why' instead of just being a match, allowing the student to learn the underlying rule (no slicing on dicts).", + "why_maybe_unnecessary": "The student can already find the answer by matching the exact question text.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:51:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q07", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q07", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "[1, 4, 3, 8, 5]", + "b": "[2, 4, 6, 8, 10]", + "c": "[1, 2, 3, 4, 5]", + "d": "[2, 2, 6, 4, 10]" + }, + "correct": "a", + "explanation": "The list comprehension doubles only the even numbers and leaves the odd numbers unchanged, so the result is [1, 4, 3, 8, 5].", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x * 2 if x % 2 == 0 else x for x in numbers]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Directly explains that 'x % 2 == 0' in a list comprehension context is used to identify even numbers, which is the core logic required to solve the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the modulo operator for even numbers within a list comprehension." + }, + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Provides another example of 'i % 2 == 0' being used to check parity, reinforcing the concept." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Explicitly states that using a mask to find even numbers involves checking the index/value parity, confirming the logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Covers list comprehension structure and parity check logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain 'x % 2 == 0' as 'even', but none explicitly explain the ternary syntax 'x * 2 if condition else x' used within the comprehension. A student might guess it, but it's not fully defined.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The parity check (modulo) is well-covered, but the specific 'if-else' conditional expression syntax inside a list comprehension is missing.", + "missing_concepts": [ + "ternary conditional expressions (value if condition else other_value)", + "list comprehension with if-else vs list comprehension with just if (filtering)" + ], + "proposed_fix": "Add a snippet or detail explaining the difference between 'if' at the end of a comprehension (filtering) and 'if-else' at the start (transformation)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining: 'In list comprehensions, [expression_if_true if condition else expression_if_false for item in list] transforms every item based on the condition.'", + "why_helpful": "It directly addresses the syntax gap for conditional transformations in comprehensions.", + "why_maybe_unnecessary": "Clever students might infer the 'if-else' logic from general English, but formal confirmation is safer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:51:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q08", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q08", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "['10a', '30c']", + "b": "[10, 20, 30, 40]", + "c": "['a', 'b', 'c', 'd']", + "d": "['10a', '20b', '30c', '40d']" + }, + "correct": "a", + "explanation": "The loop keeps only even indices from enumerate(list1), so it uses indices 0 and 2 and appends the concatenated strings '10a' and '30c'.", + "code_context": "list1 = [10, 20, 30, 40]\nlist2 = ['a', 'b', 'c', 'd']\n\nresult = []\n\nfor index, value in enumerate(list1):\n if index % 2 == 0:\n result.append(str(value) + list2[index])\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "This snippet explicitly shows 'enumerate' being used in a loop to get both an index and a value, along with the modulo operator '%' used to check index parity (i % 2)." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Directly demonstrates the 'enumerate' function and the logic for checking even/odd indices." + }, + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Provides a clear explanation that 'x % 2 == 0' is the standard way to filter for even numbers in Python." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Explains the '.append()' method, which is necessary to understand how the 'result' list is being built." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Covers 'enumerate' and the modulo operator for indices." + }, + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Reinforces the concept of filtering even numbers using % 2." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows how lists are mutated using '.append()'." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Helps the student identify 'str' as the string type, which is relevant for the 'str(value)' call." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets collectively explain the loop structure (enumerate), the conditional logic (modulo for even indices), and the list construction (append). A student can logically deduce that for indices 0 and 2, strings are created and added to the list.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the core logic is covered, there is no explicit explanation of 0-based list indexing (list[index]), string concatenation using the '+' operator, or the specific behavior of the 'str()' function on integers.", + "missing_concepts": [ + "0-based list indexing", + "string concatenation with +", + "str() function for type conversion" + ], + "proposed_fix": "Add a foundational snippet from Week 1 or 2 that demonstrates basic list access and string operations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: labels = ['A', 'B']; msg = str(1) + labels[0]; print(msg). Explanation: str() converts numbers to text, '+' joins text, and [0] accesses the first item in a list.", + "why_helpful": "This fills the 'zero-knowledge' gap regarding the specific syntax of list indexing and string building used in the question.", + "why_maybe_unnecessary": "Indexing and '+' for strings are often considered intuitive enough for students to guess correctly if they understand the loop.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:52:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q09", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q09", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 2", + "question": "Suppose you have a list called mylist. You want to extract every third element starting from index 1 (inclusive) to the last index (inclusive) from that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\n\nthen executing the following command:\nprint(subset)\n\nshould return:\n[15, 30, 45]\n\nWhat should the blanks be filled with?", + "options": { + "a": "1:len(mylist):3", + "b": "0:len(mylist):3", + "c": "1:len(mylist)-1:3", + "d": "0:len(mylist)-1:3" + }, + "correct": "a", + "explanation": "Starting at index 1 and stepping by 3 gives positions 1, 4, and 7, which are 15, 30, and 45. Using len(mylist) as the stop value includes the last valid stepped element.", + "code_context": "subset = mylist[___:___:___]\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\nprint(subset)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "While it focuses on sorting and reversing rather than slicing, it is the only snippet that directly discusses manipulating list elements to achieve a specific output order, which is the closest conceptual match." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Discusses list manipulation and index-based logic (implicit in sorting) to reach a target output list." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions selecting specific indices (2, 4, and 6), which introduces the concept of index-based selection, even though it is in a Pandas context." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Discusses 'extracting' parts of a string, which is conceptually similar to list slicing, although the syntax differs." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Shows that lists can be transformed to reach a specific sequence." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets explain the Python slicing syntax `[start:stop:step]`. A student without prior knowledge would not know that the three blanks correspond to the start index, stop index, and step size, nor would they understand how `len(mylist)` interacts with the stop parameter.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gap is the lack of any reference to list slicing syntax and the interpretation of the colon-separated parameters within brackets.", + "missing_concepts": [ + "List slicing syntax: mylist[start:stop:step]", + "Zero-based indexing (identifying that 15 is at index 1)", + "The use of len() as a stop value to include elements until the end of the sequence" + ], + "proposed_fix": "Add a snippet from a lecture or reference guide that explicitly defines the `[start:stop:step]` syntax and provides a simple example." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Key Concept' snippet for List Slicing: 'To extract a portion of a list, use the syntax mylist[start:stop:step]. start is inclusive, stop is exclusive, and step determines the interval between elements. Example: x[1:10:2] starts at index 1 and takes every 2nd element.'", + "why_helpful": "This directly provides the syntax rules required to decode the question's blanks.", + "why_maybe_unnecessary": "Only unnecessary if the student has already covered basic sequence operations, but the prompt assumes zero prior knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:52:45Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q10", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q10", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_1", + "question": "Suppose you have the following function:\n\nWhat will be printed by the following line of code?\nprint(main())", + "options": { + "a": "True", + "b": "False", + "c": "0", + "d": "None" + }, + "correct": "d", + "explanation": "The default value of x is 0, so neither if-condition runs and the function reaches the end without returning anything, which prints None.", + "code_context": "def main(x = 0):\n if x > 0:\n return True\n\n if x < 0:\n return False\n\nprint(main())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet provides the clearest explanation of default arguments (e.g., num2 = 10), which is essential for a student to understand that the variable 'x' in the question starts with a value of 0." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explains default parameter values, helping the student identify that x equals 0 when the function is called without arguments." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Demonstrates tracing a function call that uses a default argument ('y defaults to 11') and shows how the logic branches based on inputs." + }, + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "rationale": "While the logic is at the top level rather than in a function, it shows how 'if' conditions evaluate and includes 'None' as a possible output option, which might prompt the student to consider it." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Necessary to understand the 'x = 0' default syntax." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Provides a template for tracing function execution flow with default values." + }, + { + "item_id": "aiq-1", + "rationale": "Reinforces how conditional branching ('if' and 'else') determines which code paths are executed." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover default arguments and 'if' logic well. However, no snippet explicitly explains the specific Python rule that a function returns 'None' if it reaches the end of its body without executing a 'return' statement.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gap is the 'implicit return' behavior. A student can deduce x=0 and see that neither 'if x > 0' nor 'if x < 0' will run, but they won't know what happens when a function 'runs out' of code.", + "missing_concepts": [ + "Functions return 'None' by default if no return statement is reached", + "Strict comparison: 0 is not greater than 0, and 0 is not less than 0" + ], + "proposed_fix": "Add a conceptual snippet explaining that functions without an executed return statement implicitly return 'None'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Implicit Return Values' explaining: 'In Python, if a function completes its execution without hitting a return statement, it automatically returns the special value None.'", + "why_helpful": "This is the specific 'trick' of the question. Without this rule, a student with zero knowledge might assume the function causes an error or prints nothing.", + "why_maybe_unnecessary": "Advanced students might guess 'None' by process of elimination if they realize no other value is returned, but it is a specific language feature that warrants a snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:53:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q11", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q11", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_3", + "question": "Suppose you have a variable called x which contains a list of integers as follows:\nx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nWhich of the following lines will produce an output that is different from the rest?", + "options": { + "a": "print(len(x))", + "b": "print(sorted(x, reverse=True)[0])", + "c": "print(x.index(9))", + "d": "print(sum(x[4:6]))" + }, + "correct": "a", + "explanation": "len(x) is 10, while sorted(x, reverse=True)[0] is 9, x.index(9) is 9, and sum(x[4:6]) is 4 + 5 = 9.", + "code_context": "x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "Directly explains the use of len(nums) and sum(nums) in a summary context, covering half of the functions used in the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Explains len() and sum(), which are used in options 'a' and 'd'." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Demonstrates using sorted() with reverse order and basic slicing logic, which helps with options 'b' and 'd'." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Reinforces the concept of sorted(x) in reverse order to obtain a specific list sequence." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Covers len() and sum()." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Covers sorted(reverse=True) and slicing." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover len(), sum(), and sorted(reverse=True). However, the '.index()' method (option 'c') is not explained in any of the provided candidate snippets, which is critical for a student with zero prior knowledge to verify that option 'c' results in 9.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary missing concept is the list '.index()' method. Additionally, while slicing is mentioned, a clear definition of how slicing indices (e.g., [4:6]) map to specific elements would be beneficial.", + "missing_concepts": [ + "list.index() method", + "Zero-based indexing for specific slice ranges like [4:6]" + ], + "proposed_fix": "Add a snippet or detail rule explaining that x.index(value) returns the position (index) of the first occurrence of that value." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point or AI common question explaining built-in list methods: .index(item) to find a position, and clarify that indexing starts at 0.", + "why_helpful": "This would allow the student to evaluate option 'c' (x.index(9)) which evaluates to 9.", + "why_maybe_unnecessary": "If the student infers that 'index' means 'position' and counts from 0, they might guess correctly, but it is not explicitly taught in the snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:53:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q12", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q12", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_1", + "question": "You want to write a function called main which accepts a flexible number of integers as arguments.\n\nThe function should return a dictionary with the following key-value pairs:\n- key 'sum' has a value which is the sum of all the integers passed as arguments\n- key 'pro' has a value which is the multiplicative product of all the integers passed as arguments\n- key 'pow' has a value which is a list of all the squares of the integers passed as arguments\n\nWhich of the following lines of code will complete the function to give what you need?", + "options": { + "a": "x['sum'] = sum(args)\nx['pro'] = 1\nx['pow'] = []\nfor i in args:\n x['pro'] *= i\n x['pow'].append(i**2)", + "b": "x['sum'] = sum(args)\nx['pro'] = i for i in args\nx['pow'] = [i**2 for i in args]", + "c": "for i in args:\n x['sum'] = sum(args)\n x['pro'] *= i\n x['pow'] = [i**2 for i in args]", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "Option A correctly stores the sum, initializes the product accumulator to 1 before multiplying through the arguments, and builds the list of squares for each integer.", + "code_context": "def main(*args):\n x = {}\n\n # missing lines\n # ...\n\n return x" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "Directly demonstrates returning a dictionary with keys and using the sum() function on a list of integers, which covers two major requirements of the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Shows dictionary construction and aggregate functions like sum() and len()." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Provides a template for initializing a dictionary (y = {}) and using a for-loop to populate it, matching the structure of the correct answer." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Validates the '*args' syntax for functions accepting a flexible number of arguments." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Dictionary syntax and sum function." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Loop-based dictionary population pattern." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Flexible argument (*args) syntax." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows another example of a loop inside a function to process an iterable into a dictionary." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover dictionary creation, *args syntax, and the sum() function. However, they do not explain the product accumulation logic (pro = 1, pro *= i) or the power operator (**2), which are necessary to confidently choose option 'a' over distractors.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student can understand how to handle *args and return a dictionary, but lacks information on iterative product calculation and exponentiation syntax.", + "missing_concepts": [ + "product accumulation pattern (initializing to 1)", + "exponentiation operator (**)", + "list.append() method" + ], + "proposed_fix": "Add a snippet demonstrating a function that calculates both a running total and a running product using a loop, including list operations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing a function: def stats(*args):\n total = 0\n product = 1\n squares = []\n for n in args:\n total += n\n product *= n\n squares.append(n**2)\n return total, product, squares", + "why_helpful": "This covers every missing concept: the product identity (1), the *= operator, the ** exponentiation, and the append() method.", + "why_maybe_unnecessary": "If students are expected to know basic operators from other contexts, but for zero Python knowledge, this is critical.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:53:51Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q13", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q13", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 2", + "question": "You have the following objects loaded in Python:\nitem = \"laptop\"\nprice = 1299.99\n\nYou need to print the following sentence:\nThe laptop is priced at $1299.99.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(message)", + "b": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(mesage)", + "c": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)", + "d": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)" + }, + "correct": "a", + "explanation": "Option A correctly uses positional placeholders and prints the defined variable `message`. Option B appears to use a misspelled variable name in the print call, and C/D mix named placeholders with positional arguments.", + "code_context": "item = \"laptop\"\nprice = 1299.99" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "While it focuses on .map() and .split() rather than formatting, it is the only snippet categorized under 'String Fundamentals', though it provides no help for f-strings or .format()." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Categorized under string fundamentals, but content is irrelevant to formatting." + } + ], + "minimal_sufficient_snippets": [], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the candidate snippets explain Python string formatting methods (.format() or f-strings), positional/named placeholders, or the basic requirement that variable names in print() must match their definitions exactly (to catch the typo in option B).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of content regarding string interpolation and formatting syntax.", + "missing_concepts": [ + "The .format() method syntax", + "Positional placeholders ({0}, {1})", + "Named placeholders ({item}, {price})", + "Variable name case-sensitivity and spelling requirements" + ], + "proposed_fix": "Add a source material snippet or exam question that demonstrates the .format() method with both positional and keyword arguments." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining string formatting: 'The .format() method inserts values into strings. Positional placeholders like {0} and {1} correspond to the order of arguments in .format(first, second). Named placeholders like {name} require matching keywords in .format(name=\"value\").'", + "why_helpful": "It directly enables a student to understand why Option A (positional) works and why Options C/D (named vs positional mismatch) fail.", + "why_maybe_unnecessary": "Only if the student already knows Python, but the goal is zero prior knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:54:06Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q14", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q14", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 1", + "question": "Suppose you have run the following block of code:\n\nimport pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)\n\nWhich of the following lines of code give(s) the following output?\n1 4\n2 5\n3 6\nName: B, dtype: int64", + "options": { + "a": "df.loc[:, 'B']", + "b": "df['B'].loc[:]", + "c": "df['B']", + "d": "All of the given lines." + }, + "correct": "d", + "explanation": "Each of A, B, and C selects the same Series containing column `B`, so the correct choice is that all listed lines produce the shown output.", + "code_context": "import pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the standard syntax df['A'] and df['B'] for accessing columns in a DataFrame, which directly validates option 'c' and provides a baseline for Pandas indexing." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates basic column selection using bracket notation." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using df.loc for indexing and selecting specific columns, though it focuses on row filtering." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame and mentions the intent to select data to create new structures." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Validates bracket indexing for columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Introduces the concept of using .loc for selection." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets confirm that df['B'] is valid syntax for selecting a column. However, there is no explicit information explaining that df.loc[:, 'B'] is equivalent or that a Series returned by df['B'] can be further indexed with .loc[:]. A student would likely identify 'c' but might struggle to be certain about 'a' and 'b' without prior knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets show basic bracket indexing but lack examples of multi-axis selection using .loc or the fact that column selection returns a Series object that supports its own indexing.", + "missing_concepts": [ + "pandas .loc multi-axis selection (rows, columns)", + "equivalence of different column selection methods", + "indexing on a Series object returned from a DataFrame" + ], + "proposed_fix": "Add a snippet or detail rule explaining that df.loc[:, 'col'] selects all rows for a column, and that df['col'] returns a Series which itself supports .loc syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet illustrating the equivalence of df['col'], df.loc[:, 'col'], and df.iloc[:, col_index] for column selection.", + "why_helpful": "It directly addresses the core of the question (multiple ways to select the same data) which is a common pattern in introductory Python exams.", + "why_maybe_unnecessary": "Basic bracket notation is often sufficient for simple tasks, but this specific question tests 'all of the above' scenarios.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:54:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q15", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q15", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_1", + "question": "Which code segment gives the same output as the following?\n\ndate = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))\n\nYou may assume that datetime and timedelta classess are already imported from the datetime module.", + "options": { + "a": "print(datetime.strptime('22-05-2023', '%d.%m.%Y'))", + "b": "print('02-05-2023')", + "c": "print(datetime.strptime('05.22.2023', '%d-%m-%Y'))", + "d": "date = datetime.strptime('10/05/2023', '%d/%m/%Y')\nprint((date + timedelta(days=5)).strftime('%m-%d-%Y'))" + }, + "correct": "b", + "explanation": "The original code parses May 12, 2023 and subtracts 10 days, so the printed result is the string `02-05-2023`.", + "code_context": "date = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the most relevant snippet as it explicitly mentions the Datetime module and explains that operations involving datetime objects involve the timedelta class." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Provides the crucial connection between datetime objects and the timedelta class." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Shows example usage of the datetime class and basic arithmetic (subtraction)." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains the print function, which is necessary to understand how the final result is displayed." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Identifies the core library and the timedelta concept." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Demonstrates datetime class syntax." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain the 'strptime' or 'strftime' methods, nor do they define the format codes like %m, %d, or %Y. A student with zero knowledge would not know if '05.12.2023' is May 12th or December 5th, nor would they know how to format the final string.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing core documentation for string-to-date parsing, date-to-string formatting, and the specific format code syntax.", + "missing_concepts": [ + "datetime.strptime() method for parsing strings", + "datetime.strftime() method for formatting dates", + "Datetime format codes (%d, %m, %Y)", + "timedelta(days=...) constructor syntax" + ], + "proposed_fix": "Add a reference snippet that explicitly defines strptime/strftime and lists common format codes for days, months, and years." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Datetime Formatting Reference' snippet: 'Use datetime.strptime(text, format) to read a date, and date.strftime(format) to write it. Format codes: %d=day, %m=month, %Y=year (e.g., \"%d-%m\" -> \"02-05\"). timedelta(days=n) adds or subtracts n days.'", + "why_helpful": "It provides the exact translation key needed to interpret the input string and construct the output string.", + "why_maybe_unnecessary": "While Python-specific, some students might guess %m=month and %d=day, but it is risky without confirmation.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:54:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q16", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q16", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Easy_3", + "question": "You have the following definition for a class called Shape:\n\nWhat would be the output if we execute the following commands?\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "options": { + "a": "True", + "b": "False", + "c": "An error", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "`Shape(5, 3).area` is `5 * 3 = 15`, and `Shape(1, 15).length` is `15`, so the comparison evaluates to `True`.", + "code_context": "class Shape:\n def __init__(self, height, length):\n self.height = height\n self.length = length\n self.area = self.height * self.length\n\nprint(Shape(5, 3).area == Shape(1, 15).length)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Explains the fundamental structure of a class, the __init__ method, and how attributes (like name and mode) are initialized at the time of object construction, which is the core logic needed to understand the Shape class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the blueprint for understanding class initialization and attribute assignment." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Demonstrates that the '==' operator performs a comparison and returns a boolean value (True/False), which is the final step of the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to access and compare object attributes (like review scores), illustrating the 'object.attribute' syntax used in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Teaches __init__ and attribute setup." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Teaches comparison logic and output types." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Teaches dot-notation for attribute access." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class structure, initialization, and comparison logic. However, a student with zero knowledge might still struggle to trace how 'Shape(5, 3)' maps to 'self.height' and 'self.length' specifically, as the snippets don't explicitly walk through the calculation of a third attribute (area) based on inputs.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main gap is an explicit explanation of how positional arguments in an instantiation call map to the __init__ method's parameters, and how calculated attributes are stored.", + "missing_concepts": [ + "positional argument mapping in __init__", + "calculated attributes vs passed attributes", + "tracing multiple object instances in one expression" + ], + "proposed_fix": "Add a snippet that defines a simple class with a calculated attribute (e.g., Circle with radius and area) and shows the step-by-step trace of creating the object and accessing both attributes." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet titled 'OOP: Calculated Attributes' showing a class Rectangle(width, height) that sets self.area = width * height. It should include a comment: 'Rectangle(2, 5) makes width=2, height=5, and area=10'.", + "why_helpful": "It directly mirrors the logic of the question (Shape with area = height * length), making the trace obvious to a non-programmer.", + "why_maybe_unnecessary": "The 'Vehicle' snippet covers 80% of the logic; the user might be able to 'jump' the remaining gap.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:55:14Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q17", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q17", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "6-string - operations - 2", + "question": "Write a function called shuffle_sentence that takes a string as an argument and returns a new string where the words are shuffled randomly.\n\nFor example, if your function is called as:\nshuffle_sentence(\"Hello, how are you today?\")\nthen it could return a shuffled string like:\n'how today? you Hello, are'\n\nWhich of the following programs work(s) according to the requirements?\n\nHints:\nThe shuffle() function is a method from the random module. The shuffle() method takes a sequence, like a list, and reorganizes the order of the items. This method changes the original list; it does not return a new list.\nThe reversed() function computes the reverse of a given sequence object and returns it in the form of a list.", + "options": { + "a": "def shuffle_sentence(sentence):\n words = sentence.split()\n return ' '.join(reversed(words))", + "b": "import random\n\ndef shuffle_sentence(sentence):\n words = sentence.split()\n random.shuffle(words)\n return ' '.join(words)", + "c": "Both of the programs work.", + "d": "Neither of the programs work." + }, + "correct": "b", + "explanation": "Option B is the only one that actually shuffles the words randomly. Option A only reverses the word order, which does not satisfy the random-shuffle requirement.", + "code_context": "shuffle_sentence(\"Hello, how are you today?\")\n# could return: 'how today? you Hello, are'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "Explicitly teaches the concept of in-place mutation ('Check whether the method mutates the list in place'), which is critical for understanding why random.shuffle(words) is called on its own line in the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Focuses on method mutation, helping the student understand the 'random.shuffle' hint provided in the question." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the 'reverse()' method, providing a helpful contrast to the 'reversed()' function mentioned in the question's hints." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Explains that strings are immutable and methods like .replace() return new strings, helping students differentiate between string methods and list mutations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Covers mutation vs returning new objects." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Covers method vs function syntax (reverse vs reversed)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Covers string immutability." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The question hints explain 'shuffle' and 'reversed' behavior, and 'aiq-2' reinforces the mutation concept. However, none of the snippets explicitly explain '.split()' or '.join()', which are the two primary mechanisms for converting between the input string and the list required for shuffling.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main missing link is the 'String-to-List' and 'List-to-String' transformation syntax.", + "missing_concepts": [ + "str.split() method for creating word lists", + "' '.join(list) syntax for reconstructing sentences" + ], + "proposed_fix": "Add a snippet or edit an existing string operation snippet to show a round-trip transformation (split and join)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Sentence Reconstruction. Content: 'To turn a sentence into a list of words, use sentence.split(). To turn a list of words back into a sentence with spaces, use \" \".join(words_list).'", + "why_helpful": "This directly provides the syntax for the only two parts of the code not explained by the question's internal hints.", + "why_maybe_unnecessary": "A student might infer split/join from the context of the options, but it's a high cognitive load for zero-knowledge users.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:55:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q18", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q18", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "6-strings - find & replace - 1", + "question": "Consider the following line of code:\n\ntext = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\n\nYou want to create a new string called new_text where all occurances of \"oil\" are replaced by \"natural gas\".\n\nSo:\nprint(new_text)\nshould return:\n\"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "new_text = ' '.join([word if word != 'oil' else 'natural gas' for word in text.split()])", + "b": "new_text = text.replace(\"oil\", \"natural gas\")", + "c": "new_text = text.split()\nfor index, word in enumerate(new_text):\n if word == 'oil':\n new_text[index] = 'natural gas'\nnew_text = ' '.join(new_text)", + "d": "All of the given options works as intended." + }, + "correct": "d", + "explanation": "All three code fragments replace each occurrence of the standalone word `oil` with `natural gas`, so the correct answer is that all of them achieve the requested result.", + "code_context": "text = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\nprint(new_text)\n# should return:\n# \"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions processing strings where characters are separated by specific delimiters (dashes), which is the most related context for string cleaning/manipulation, even though the specific methods like .replace() aren't shown." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Relates to the core task of identifying and modifying specific characters or patterns within a string (phone numbers with separators)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Discusses extracting components from a string (URL TLD), which implicitly requires string partitioning or splitting logic similar to options A and C." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates string slicing and the 'list()' function, which helps a student understand that strings can be treated as sequences or converted to lists (relevant to Option C)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Context for string manipulation." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Context for string splitting." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Context for string-to-list behavior." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Mentions having a 'list of strings called words', which mirrors the output of 'text.split()' used in the question." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets explicitly mention or demonstrate the '.replace()', '.split()', or '.join()' methods. A student with zero prior knowledge would have no way to verify if 'text.replace(\"oil\", \"natural gas\")' is valid Python syntax or if it correctly handles all occurrences. The logic of list comprehensions (Option A) is also completely absent from the candidates.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate list is missing foundational string methods and sequence joining documentation.", + "missing_concepts": [ + "str.replace()", + "str.split()", + "str.join()", + "List comprehension with inline if-else" + ], + "proposed_fix": "Add a documentation snippet or a lecture card from Week 1 or Week 4 that specifically lists and examples 'String Methods for Search and Replace'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a card for 'Essential String Methods' covering split(), join(), and replace().", + "why_helpful": "This would provide the direct definitions needed for all three code segments (a, b, and c) in the question.", + "why_maybe_unnecessary": "Only unnecessary if the user assumes the student can guess method names based on English meaning.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:56:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q19", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q19", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - hard - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Select all rows where the age is greater than 30 and the gender is \"Male\".\n- Operation 2: Create a new column called Sex_abbr of which the values should be \"F\" if gender is \"Female\" and \"M\" if gender is \"Male\".\n- Operation 3: Calculate the average salary of all employees.\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df_operation1 = df[(df['Age'] > 30) & (df['Gender'] == 'Male')]\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "b": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "c": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = df['Gender'].map(lambda x: 'M' if x == 'Male' else 'F')\ndf_operation3 = df['Salary'].sum()/len(df)", + "d": "df_operation1 = df[df['Age'] > 30 & df['Gender'] == 'Male']\ndf['Sex_abbr'].map(lambda x: 'M' if x == 'Male' else 'F' for x in df['Gender'])\ndf_operation3 = df['Salary'].sum()/len(df)" + }, + "correct": "a", + "explanation": "Option A correctly filters rows with both conditions using boolean masking, builds the abbreviation column from the Gender column, and computes the average salary with mean().", + "code_context": "Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Introduces the concept of a 'boolean mask' to select rows, which is the foundational logic needed for Operation 1." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Explains boolean masking for filtering rows, relevant to Operation 1." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions the .mean() method, which is the direct solution for Operation 3 (average salary)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates how to create a new column in a DataFrame by assigning values to a new key (df['C'] = ...), relevant to Operation 2." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Covers boolean selection/masking." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides the .mean() method." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic column assignment syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions the .map() method, which helps a student evaluate options C and D, even if option A uses a list comprehension." + } + ], + "answerability": { + "status": "partial", + "confidence": "low", + "rationale": "The snippets cover individual components: row filtering (masking), column creation, and the .mean() method. However, they do not demonstrate how to combine multiple conditions using '&' (crucial for Op 1) nor do they show the specific list comprehension syntax for conditional value assignment (crucial for Op 2). A student with zero Python knowledge might struggle to synthesize these complex pandas-specific syntax rules.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets lack examples of multi-condition boolean indexing and inline conditional logic (list comprehensions) applied to DataFrame columns.", + "missing_concepts": [ + "Multi-condition boolean filtering with the & operator in Pandas", + "List comprehension for conditional column assignment (if-else inside a list)", + "Distinction between .loc() and [] for filtering" + ], + "proposed_fix": "Add a snippet or exam question that explicitly uses '&' to filter a DataFrame and assigns a new column based on a list comprehension with internal if-else logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: df_filtered = df[(df['A'] > 5) & (df['B'] == 'Yes')] and df['New'] = ['High' if x > 10 else 'Low' for x in df['A']]", + "why_helpful": "This would directly illustrate the two most complex parts of the question: combining boolean filters and using list comprehensions for data transformation.", + "why_maybe_unnecessary": "The student might infer masking from the single-condition example, though the '&' operator is a specific technical hurdle.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:56:27Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q20", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q20", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - lambda - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000\n\nYou want to create a new column called Bonus that compute each employee's bonus based on their salary and performance review using the following formula:\n- if the performance review is less than 4, the bonus is 0.\n- if the performance review is 4 or 5, the bonus is 5% of the salary.\n\nWhich of the following code snippets works as intended?", + "options": { + "a": "df['Bonus'] = df.apply(lambda row: row['Salary']*0.05 if row['Performance_review']>=4 else 0, axis=1)", + "b": "df['Bonus'] = df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>=4 else 0)", + "c": "df['Bonus'] = map(df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>4 else 0))", + "d": "df['Bonus'] = df['Salary'].map(lambda row: row*0.05 if df['Performance_review']>=4 else 0)" + }, + "correct": "a", + "explanation": "Option A evaluates each row, checks the row's Performance_review value, and returns either 5% of Salary or 0 for that employee.", + "code_context": "Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column ('C') from existing columns ('A' and 'B') in a pandas DataFrame, which matches the target question's structure for creating a 'Bonus' column." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates DataFrame column creation/assignment syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that methods like .map() allow applying functions to values, providing the conceptual bridge to .apply() and .map() used in the options." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Introduces the concept of 'applying functions' to multiple elements, which is the core logic of the .apply() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "RHS/LHS assignment for columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Usage of mapping functions." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain 'lambda' syntax, 'if/else' logic within a function call, or the crucial 'axis=1' parameter required for row-wise DataFrame operations. A student without prior knowledge wouldn't understand why Option A is superior to B or D.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets cover basic column assignment and the concept of mapping, but fail to explain higher-order function syntax (lambda) and row-wise DataFrame processing.", + "missing_concepts": [ + "lambda function syntax", + "df.apply(..., axis=1) for multi-column row logic", + "inline if-else (ternary) operators in Python" + ], + "proposed_fix": "Add a snippet or AI-generated section specifically illustrating row-wise calculations in Pandas using .apply(lambda row: ..., axis=1) with a simple conditional." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Row-wise Calculations with Lambda. Content: To create a column based on multiple other columns, use df.apply(lambda row: expression, axis=1). For example: df['Total'] = df.apply(lambda r: r['A'] + r['B'] if r['C'] > 0 else 0, axis=1).", + "why_helpful": "This directly maps to the correct answer's pattern, explaining both the multi-column access (row['Col']) and the conditional logic.", + "why_maybe_unnecessary": "If the student is expected to infer lambda from general function application, but that is unlikely for a 'zero knowledge' persona.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:56:53Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q21", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q21", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_3", + "question": "You want to create a function called main which take an integer and a flexible number of strings as arguments. The strings represent dates in the format of DD MM YYYY. The day, month and year can be separated by different characters.\n\nYour function should look for the string inputs which represent dates as DD-MM-YYYY or DD/MM/YYYY and return those strings in the format of DD.MM.YYYY in a list. Furthermore, the dates represented by the strings should be shifted by the amount of days as given by the integer argument.\n\nFor example, if we call your function as:\nmain(3, '25/06/2003', '26.06.2003', '27-06-2003', '28:06:2023', '29-06-2023', '30.06.2023')\n\nthe output should be:\n['28.06.2003', '30.06.2003', '02.07.2023']\n\nTake a look at the following code segment. Does it do what is intended? If not, then why not?", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the function will return a list of datetime objects, not a list of strings representing dates.", + "c": "This code segment does not work because the strftime() method cannot be applied to NoneType object.", + "d": "This code segment produces an error because you cannot concatenate strings and timedelta." + }, + "correct": "b", + "explanation": "The function parses matching inputs and adds the day offset, but it appends datetime objects and never converts them back to strings in DD.MM.YYYY format before returning.", + "code_context": "def main(delta, *args):\n dates = []\n for string in args:\n if '-' in string:\n dates.append(datetime.strptime(string, '%d-%m-%Y') + timedelta(days=delta))\n elif '/' in string:\n dates.append(datetime.strptime(string, '%d/%m/%Y') + timedelta(days=delta))\n else:\n dates.append(None)\n return [date for date in dates if type(date) != None]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that demonstrates the use of a flexible number of arguments (*args) and discusses function definitions working 'as intended', which matches the structure and syntax of the exam question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains flexible arguments (*args), which is central to the function signature provided in the code context." + }, + { + "item_id": "aiq-4", + "rationale": "Provides an example of a function taking a flexible number of arguments and discusses return types, which is relevant to the correct answer (b)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Focuses on formatting strings as output from functions, providing a conceptual link to the 'intended' vs 'actual' string formatting failure in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers the *args syntax used in the question." + }, + { + "item_id": "aiq-4", + "rationale": "Reinforces flexible argument handling and return behavior." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the available snippets mention the datetime library, strptime, timedelta, or the difference between a datetime object and a formatted string. A student with zero Python knowledge would have no way to know that datetime.strptime returns an object rather than a string, or how to distinguish between the two types in the context of option (b).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets only cover function signatures (args/kwargs) but completely lack technical documentation for the datetime module which is the core subject of the question.", + "missing_concepts": [ + "datetime.strptime return type", + "datetime.strftime for string conversion", + "timedelta for date arithmetic", + "The difference between an object type and a string representation" + ], + "proposed_fix": "Add a dedicated snippet explaining the Datetime module, specifically showing that strptime creates objects and strftime creates strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Working with Datetimes. Content: Use `datetime.strptime(date_string, format)` to convert a string to a datetime OBJECT. Use `dt_object.strftime(format)` to convert it back to a STRING. Use `timedelta(days=n)` to add/subtract days from a datetime object.", + "why_helpful": "This provides the missing technical knowledge required to understand why the code returns objects (Option B) instead of the desired strings.", + "why_maybe_unnecessary": "The topic might be covered in later weeks, but since the question is about Datetime Function 3, it's essential for this specific task.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:57:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q22", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q22", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_2", + "question": "You want to define a class called Calendar, which has four attributes that are initialized at the time of object construction:\n1. The 'event' attribute can be any string,\n2. The 'date' attribute is a string representing a date as 'DD-MM-YYYY',\n3. The 'start' attribute is a string representing the time as 'HH:MM', and\n4. The 'length' attribute is an integer representing the amount of minutes.\n\nThe class should also have a method called get_details() that gives a description of Calendar objects.\n\nFor example, if we execute the following commands;\nevent1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n\nthe output should be:\nCoffee meeting: 01-06-2023, 9:30-9:50.\n\nWhich of the following code segments gives you what you want?", + "options": { + "a": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day, int(start.split(':')[0]), int(start.split(':')[1]))\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "b": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.split(':')[0], minute=start.split(':')[1])\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "c": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.hour, minute=start.minute)\n self.end = self.self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "d": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start.hour = start.hour\n self.start.minute = start.minute\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'" + }, + "correct": "a", + "explanation": "Option A is the only choice that correctly parses the date string, combines the parsed date with the split start time to build a datetime, adds the duration in minutes, and formats the requested details string.", + "code_context": "event1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n# output:\n# Coffee meeting: 01-06-2023, 9:30-9:50." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-format", + "rationale": "This snippet provides the essential syntax for datetime construction, strftime formatting, and explicitly mentions strptime and timedelta, which are the core components needed to solve the datetime logic in Option A." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-format", + "rationale": "Covers datetime parsing, formatting, and object creation, which are the primary technical hurdles in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows the standard boilerplate for defining a class with an __init__ method and multiple attributes, which is the required structure for the Calendar class." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Introduces the concept of timedelta objects, helping the student identify that time arithmetic (like adding minutes) requires this specific class." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-format", + "rationale": "Provides datetime parsing/formatting logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides class and constructor structure." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Contextualizes timedelta for time calculations." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates f-string interpolation which is used in the get_details() method return statement." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The available snippets cover class structure and basic datetime formatting (strftime/strptime). However, the specific logic of using .split(':') to parse a time string and the exact syntax for adding minutes via timedelta(minutes=...) are not explicitly demonstrated, making the 'Hard' part of the question difficult for a zero-knowledge student.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the high-level components (Classes, Datetime) but lack the connective tissue for string manipulation and specific timedelta parameter usage.", + "missing_concepts": [ + "string.split() for parsing time", + "timedelta(minutes=...) parameter usage", + "accessing attributes from another object (self.date.year, etc.)" + ], + "proposed_fix": "Add a new example snippet that demonstrates parsing a string like 'HH:MM' into a datetime object using split and performing minute-based arithmetic with timedelta." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Parsing Time Strings and Minute Arithmetic\nfrom datetime import datetime, timedelta\nstart_str = '9:30'\nh, m = start_str.split(':')\nstart_dt = datetime(2023, 6, 1, int(h), int(m))\nend_dt = start_dt + timedelta(minutes=20)\nprint(f'End: {end_dt.strftime(\"%H:%M\")}')", + "why_helpful": "This directly models the logic required in the __init__ method of the question, specifically the combination of string splitting, int conversion, and timedelta usage.", + "why_maybe_unnecessary": "A student might guess split() based on common sense, but the timedelta(minutes=...) syntax is hard to intuit without an example.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:57:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q23", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q23", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Function_2", + "question": "You have the following definition for a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nYou want to add three methods to this class:\n1. The holiday_bonus() method which computes and returns the holiday bonus, which is 8.0% of the yearly salary,\n2. The year_end_bonus() method which computes and returns the year end bonus, which is 8.3% of the yearly salary\n3. The payment_overview() method which returns a payment overview of the employee using the following format:\n[Name] receives $[salary] monthly, $[holiday bonus] in May and $[year end bonus] in December.\n\nFor example, if we execute the following commands:\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())\n\nthe output should be:\n2400.0\n2490.0\nJohn Smith receives $2500 monthly, $2400.0 in May and $2490.0 in December.\n\nWhich of the following code segments should you place on the blank in the class definition to achieve what you want?", + "options": { + "a": "def holiday_bonus(self):\n return self.salary * 12 * 0.080\ndef year_end_bonus(self):\n return self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus()} in May and ${self.year_end_bonus()} in December.'", + "b": "def payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.salary*12*0.08} in May and ${self.salary*12*0.083} in December.'", + "c": "def holiday_bonus():\n self.holiday_bonus = self.salary * 12 * 0.080\ndef year_end_bonus():\n self.year_end_bonus = self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'", + "d": "def payment_overview(self):\n self.holiday_bonus = self.salary * 12 * 0.080\n self.year_end_bonus = self.salary * 12 * 0.083\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'" + }, + "correct": "a", + "explanation": "Option A defines all three requested methods, computes the two bonuses from the yearly salary, and uses those method results in the overview string.", + "code_context": "class Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "It introduces the concept of defining a custom method within a class to perform logic based on object attributes, which is the primary requirement for solving the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Provides the conceptual framework for adding functional methods (like 'compare') to a class." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows basic class definition syntax and attribute initialization using 'self', which helps a student understand the 'self.attribute' references in the options." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string formatting with placeholders (e.g., [NAME]), which is helpful for identifying the correct format of the payment_overview return string." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Conceptual method definition." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Standard class/self syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "String interpolation pattern." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the selected snippets explain class structure and basic string formatting, they do not demonstrate two critical Python OOP requirements: 1) that 'self' must be the first parameter in a method definition, and 2) that calling an internal method requires the 'self.method_name()' syntax. Without these, a student cannot confidently choose (a) over (c) or (d).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets cover 'what' to do (define methods) but not the 'how' (the specific syntax of self and internal method calls).", + "missing_concepts": [ + "Mandatory 'self' parameter in instance method definitions", + "Accessing instance methods via 'self.method_name()'", + "Calling methods within f-strings" + ], + "proposed_fix": "Add a snippet showing a class where one method calls another method using 'self', specifically demonstrating the use of parentheses for the call." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for a 'Circle' class that has a 'radius' attribute, an 'area(self)' method, and a 'summary(self)' method that returns f'Area is {self.area()}'.", + "why_helpful": "This would explicitly teach the student that methods need 'self' as an argument and 'self.' prefix with parentheses to be called, directly addressing the distractors in options C and D.", + "why_maybe_unnecessary": "It is a fundamental OOP concept, but 'zero knowledge' students require an explicit code example of method-to-method calling.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:58:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:final-exam-study-guide-trial-python-basics-2023-q24", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q24", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Hard_2", + "question": "You have the following definitions for a class called Car:\n\nclass Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nYou want to create another class called Garage, which has two attributes that are initialized during object construction:\n- The 'capacity' attribute, which is an integer and must be passed to the object constructor.\n- The 'cars' attribute, which is an empty list.\n\nThe Garage class should also have two methods:\n1. The add_car() method, which adds Car objects to a Garage object. New Car objects can only be added if there is still capacity in the Garage object. If not, the method should return \"Capacity reached.\"\n2. The check_garage() method, which reports the Car objects that have been added to the Garage object. The method should return a dictionary in which the keys are the counts of Car objects starting from 1 and the values are the Car objects' descriptions.\n\nFor example, if we execute the following commands:\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n\nthe output should be:\n{1: 'Toyota, Camry', 2: 'Honda, Accord'}\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "class Garage:\n def __init__(self, capacity, cars = []):\n self.capacity = capacity\n\n def add_car(self, car):\n self.cars += car if len(self.cars) < self.capacity else return 'Capacity reached.'\n\n def check_garage(self, car):\n return {index: car.get_description() for index, car in enumerate(self.cars, start=1)}", + "b": "class Garage:\n def __init__(self, capacity):\n self.capacity = capacity\n self.cars = []\n\n def add_car(self, car):\n if len(self.cars) < self.capacity:\n self.cars.append(car)\n else:\n return 'Capacity reached.'\n\n def check_garage(self):\n output = {}\n for index, car in enumerate(self.cars, start=1):\n output[index] = car.get_description()\n return output", + "c": "Both of the above will work.", + "d": "None of the above will work." + }, + "correct": "b", + "explanation": "Option B initializes capacity and an empty cars list, appends cars only when capacity remains, returns the required message when full, and builds the requested dictionary in check_garage().", + "code_context": "class Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n# output:\n# {1: 'Toyota, Camry', 2: 'Honda, Accord'}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows the basic structure of a Python class definition and the __init__ method for attribute initialization, which is central to the Garage class requirements." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides a template for defining a class and initializing multiple attributes, including those passed to the constructor." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the specific dictionary output format {1: 'I', 2: 'II'} requested in the check_garage method, helping the student recognize the target structure." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Illustrates the logic of mapping list elements to dictionary keys, which is required for the check_garage method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Class/Init structure." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Target dictionary output pattern matching." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Basic dictionary creation logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the 'outer shell' (Class definition, attribute initialization, and dictionary output format). However, they do not explain the behavior of 'list.append()' vs 'list += object' or the specific 'enumerate(..., start=1)' syntax, which are necessary to distinguish between options A and B.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student lacks information on how to add an item to a list attribute and how to use enumeration to generate sequential keys in a dictionary.", + "missing_concepts": [ + "list.append() method", + "enumerate(list, start=1) syntax", + "Default mutable argument trap (Option A uses cars=[])", + "Difference between list += item and list.append(item)" + ], + "proposed_fix": "Add a snippet demonstrating a class that manages a list of items, showing how to append to the list and how to iterate through it using enumerate to produce a dictionary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet (e.g., 'OOP Method with List and Enumerate') that shows a class 'Inventory' with an 'items' list, an 'add_item' method using '.append()', and a 'get_indexed_items' method returning a dictionary using 'enumerate(self.items, start=1)'.", + "why_helpful": "Directly demonstrates the mechanics needed to solve '9_OOP_Hard_2', specifically list mutation and dictionary generation with custom start indices.", + "why_maybe_unnecessary": "If the student already understands list basics from a separate 'Lists' section, this might be redundant, but for zero-knowledge students, this bridge is vital.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:58:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round1/introduction-to-python-trial-final-exam-solutions-py22.json b/data/vision_exam_pipeline/work_packets/evaluations/round1/introduction-to-python-trial-final-exam-solutions-py22.json new file mode 100644 index 0000000..11c3628 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round1/introduction-to-python-trial-final-exam-solutions-py22.json @@ -0,0 +1,2191 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q01", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q01", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_3", + "question": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?", + "options": { + "a": "if x in list(range(11))[::2]:\n print('Even number')\nelse:\n print('Odd number')", + "b": "if x % 2 != 0:\n print('Odd number')\nelse:\n print('Even number')", + "c": "if x in [1, 3, 5, 7, 9]:\n print('Odd number')\nelse:\n print('Even number')", + "d": "All of the programs work as intended." + }, + "correct": "d", + "explanation": "Option A checks membership in the even numbers from 0 through 10, option B checks oddness with modulo, and option C checks membership in the odd numbers from 1 through 9. All three correctly classify x as odd or even in the stated range.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive). Which of the following programs will tell you whether x contains an odd or eve", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-1-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-1-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "This snippet is a verbatim copy of the same question from a previous exam year and explicitly states that 'All three programs correctly identify whether x is odd or even', pointing directly to the correct answer (d)." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Directly contains the identical question, answer key, and logic explanation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates slicing syntax [1::2] on a list, which helps a student understand how the slicing [::2] in Option A functions." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Mentions filtering and summing even integers, providing a conceptual link to parity (even/odd) logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "This snippet alone provides the exact solution and reasoning for the specific problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of a verbatim match from a trial exam makes the question answerable without any understanding of the underlying Python code, as the student can simply match the text and see the stated answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the verbatim match exists, there is a total lack of conceptual documentation for the modulo operator (%) and the range() function, which are critical for actually understanding the options.", + "missing_concepts": [ + "Modulo operator (%) for checking parity (even/odd)", + "range(n) function behavior", + "Step slicing syntax [::step]" + ], + "proposed_fix": "Add a foundational snippet explaining basic Python arithmetic (specifically modulo) and how range(n) creates sequences of numbers." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Arithmetic and Logic Basics: Explain that 'x % 2 == 0' checks if a number is even (no remainder) and 'x % 2 != 0' checks if it is odd. Explain that range(11) creates numbers 0 to 10.", + "why_helpful": "This allows the student to verify Option B and Option A independently rather than relying on a verbatim question match.", + "why_maybe_unnecessary": "If the goal is purely 'cheating' by pattern matching, the existing verbatim snippet is sufficient.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:59:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q02", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q02", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_2", + "question": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "options": { + "a": "This code will produce an error because a is a global name that is referenced inside the local scope of inner().", + "b": "This code will not produce any error and will return 30.", + "c": "This code will produce an error because c is not defined before referencing.", + "d": "This code will not produce any error and will return 50." + }, + "correct": "b", + "explanation": "The function inner receives c as its argument, so c is defined. It can also read the global a. inner(5) returns 1 + 5 + 4 = 10, and outer returns 10 * 3 = 30.", + "code_context": "a = 1\ndef outer(b):\n b = 3\n def inner(c):\n d = 4\n return a + c + d\n return inner(5) * b\nouter(5)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "rationale": "This is an exact match for the question, providing the full trace and mathematical calculation (10 * 3 = 30) that confirms why there is no error." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "rationale": "Directly answers the specific question and code provided." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the underlying rules: global names are known everywhere except where a local name dominates, justifying why 'a' is accessible inside 'inner'." + }, + { + "item_id": "manual-unboundlocal", + "rationale": "Explains that assignment makes a name local, which helps understand why 'b' in outer(5) becomes 3 and stays local to outer." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "rationale": "Contains the specific solution." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the general logic for global/local name access." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact exam question and its explanation, as well as the fundamental lecture theory on scope rules.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact answer is present, there is no explicit mention of 'Enclosing Scope' or 'Nested Functions' in the theory snippets, which might confuse a total beginner seeing a function inside a function for the first time.", + "missing_concepts": [ + "Nested function definitions", + "Enclosing (non-local) scope" + ], + "proposed_fix": "Add a conceptual snippet explaining that functions can be defined inside other functions and can access variables from the outer function's scope." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Nested Functions and Enclosing Scope. Content: Python allows defining a function (inner) inside another function (outer). The inner function can access variables defined in the outer function (its enclosing scope) as well as global variables. Example: def outer(x): y=10; def inner(z): return x+y+z; return inner.", + "why_helpful": "It explains the structure of the code context, which involves nested functions—a concept not explicitly covered in the 'Global vs Local' snippet.", + "why_maybe_unnecessary": "A student might simply follow the trace in the existing exam-match snippet without needing the formal definition of nested scopes.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:59:26Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q03", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q03", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_2", + "question": "What will be returned by the following code segment?", + "options": { + "a": "[0, None, 2, 3, None, 5, 6, 7, 8, None]", + "b": "[0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, 9]", + "c": "[None, 1.0, None, None, 3.5, None, None, None, None, '9']", + "d": "[0, None, 2, 3, None, 5, 6, 7, 8, 9]" + }, + "correct": "a", + "explanation": "The function appends each item if its exact type is int; otherwise it appends None. In the given list, 1.0, 3.50, and '9' are not ints, so those positions become None.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n if type(item) == int:\n list_2.append(item)\n else:\n list_2.append(None)\n return list_2\n\nmain([0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, '9'])" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What will be returned by the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ], + "evidence_topics": [ + "Return Behavior" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "This snippet explicitly explains the exact logic of the question: that 1.0 and 3.50 are floats and '9' is a string, so they do not match the 'int' type check and are replaced by None." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Provides the direct explanation for why floats and strings are excluded in a type-check for integers." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Clearly labels different Python types (str, int, float, etc.), helping a student identify that 1.0 is a float and '9' is a string." + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Shows a similar code structure using a loop and a type comparison (type(i) == type(x)) to build a new list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Directly explains the logic and the specific values in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet is a near-perfect match for the question's logic and explanation, making the answer obvious even without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective because one of them appears to be a direct explanation of this specific exam question or a very similar variant.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T18:59:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q04", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q04", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 2", + "question": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}", + "b": "roman_nums = {roman: num for roman, num in zip(['I', 'II', 'III', 'IV', 'V'], range(1, 6))}", + "c": "roman_nums = {num: ['I', 'II', 'III', 'IV', 'V'][num] for num in range(1, 6)}", + "d": "roman_nums = {num: roman for num, roman in zip(range(1, 6), 'I II III IV V')}" + }, + "correct": "a", + "explanation": "Option A zips the integers 1 through 5 with the five Roman numeral strings and builds the required dictionary. The other options either reverse the keys and values, use incorrect indexing, or iterate over a plain string instead of the intended list of numerals.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols. Tha", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet explicitly mentions creating a dictionary from a list where keys are strings and values are lengths, which typically uses the dictionary comprehension syntax {k: v for ...} required for the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides the conceptual pattern for dictionary comprehension (mapping keys to values in a new dict)." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Introduces the use of 'zip' with names and ages to create a dictionary, which is the specific mechanism used in the correct answer (Option A)." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While it is a duplicate of the question, having the problem statement on the sheet helps a student recognize the task, though it lacks the implementation details in its current truncated form." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows that dictionary creation often involves iterating over a collection to map keys to values." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Explicitly connects 'zip' with dictionary creation from two lists." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the 'zip' concept and the 'dictionary comprehension' concept separately. A student would need to infer that they can be combined into '{k: v for k, v in zip(...)}'. No single snippet shows the combined syntax clearly enough for someone with zero Python knowledge to be certain.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no snippet that demonstrates the specific syntax of a dictionary comprehension using zip: {key: value for key, value in zip(list1, list2)}.", + "missing_concepts": [ + "dictionary comprehension syntax with zip", + "range(start, end) behavior (inclusive/exclusive)" + ], + "proposed_fix": "Add or modify a snippet to show a complete, valid dictionary comprehension example that uses zip() on a range and a list." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "proposal": "Update the search_text/content to include the correct code segment: 'roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}'.", + "why_helpful": "It provides the direct answer and the exact syntax for the comprehension + zip pattern.", + "why_maybe_unnecessary": "If the goal is to teach the principle rather than give the answer, a generic zip-comprehension example might be better.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a summary snippet for 'Dictionary Comprehensions' showing: {k: v for k, v in zip(keys, values)} and explaining that range(1, 6) produces 1, 2, 3, 4, 5.", + "why_helpful": "It bridges the gap between the individual components (zip and comprehension) and explains the range function logic.", + "why_maybe_unnecessary": "None; this is a core missing piece for zero-knowledge users.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:00Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q05", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q05", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 2", + "question": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to only include the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[name] = age", + "b": "person_dict = {}\nfor i, name in enumerate(names):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[i] = ages[i]", + "c": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict.append(name:age)", + "d": "person_dict = {}\nfor i, name in enumerate(names):\n for j, letter in enumerate(name):\n if letter == 'A' or letter == 'C':\n person_dict[i] = ages[j]" + }, + "correct": "a", + "explanation": "Option A correctly iterates over names and ages together and stores only the names beginning with A or C as keys mapped to their ages. The other options use indices as keys, invalid dictionary syntax, or incorrect nested-loop logic.", + "code_context": "names = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have two lists representing the names and ages of individuals: names = ['Alice', 'Bob', 'Charlie', 'David'] ages = [25, 30, 35, 40] You need to create a dictionary called perso", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This snippet is an exact match for the exam question provided, containing the same scenario, variable names (names, ages), and requirements." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Directly matches the question context and logic requirements." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the standard syntax for creating a dictionary from a list (keys) and mapping them to values (lengths), which reinforces the dict[key] = value pattern used in the correct answer." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Shows conditional logic within a loop to update a dictionary (if letter in counts), which helps a student understand the structure of the correct option's loop." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides the specific problem context and likely the options or solution pattern." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Validates the dictionary assignment syntax needed to distinguish Option A from Option C (which uses an invalid .append() method)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the source version of the exact same question. Even if they didn't, other snippets demonstrate dictionary assignment syntax and looping, which are the core concepts needed.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main technical hurdle is understanding 'zip()' and string indexing 'name[0]'. While 'name[0]' is somewhat intuitive, 'zip()' is a specific Python function not explicitly defined in the other dictionary snippets.", + "missing_concepts": [ + "zip() function functionality", + "String indexing for first character (name[0])" + ], + "proposed_fix": "Add a snippet or detail rule explaining how zip() combines two lists into pairs for iteration." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Syntax' card for the 'zip()' function that shows: for x, y in zip(list1, list2): ...", + "why_helpful": "It clarifies how the loop in the correct answer manages to access both 'name' and 'age' simultaneously without using an index variable.", + "why_maybe_unnecessary": "The student might infer the behavior from the context of the question/answer pair, but a definition ensures certainty.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q06", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q06", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 2", + "question": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?", + "options": { + "a": "max_rating = max(employee_ratings.values())\nfor employee, rating in employee_ratings.items():\n if rating == max_rating:\n print(employee)", + "b": "max_rating_employee = max(employee_ratings.keys())\nfor employee, rating in employee_ratings.items():\n if employee == max_rating_employee:\n print(employee)", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "a", + "explanation": "Option A correctly computes the maximum rating value and prints every employee whose rating matches it. Option B instead finds the maximum key lexicographically, not the employee with the highest rating.", + "code_context": "employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You have the following dictionary that represents the performance ratings of employees in a company: employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text and context, providing the most direct path to the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Exact match for the exam question being asked." + }, + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the pattern of iterating through a dictionary (math_scores) to find names based on a value-derived condition." + }, + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "rationale": "Discusses finding highest and lowest values within dictionaries, which reinforces the concept of max/min operations on dictionary values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Contains the specific scenario and logic required." + }, + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Provides a secondary example of filtering dictionary keys (names) by their associated values (scores)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the exact question being evaluated. A student can simply identify the matching problem description to find the solution.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact question is present, there is a lack of a general 'rule' snippet that explicitly explains the difference between max(dict) (keys) and max(dict.values()).", + "missing_concepts": [ + "Explicit comparison between max(dict.keys()) and max(dict.values())", + "Explanation of .items() unpacking in a for-loop" + ], + "proposed_fix": "Add a summary card or 'Cheat Sheet Rule' that clarifies how to find the 'Key with the Maximum Value' versus the 'Maximum Key'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Max/Min Patterns' reference card. Example: To find the key with highest value, use max_val = max(d.values()) then loop if val == max_val. To find highest key alphabetically, use max(d).", + "why_helpful": "This helps a student solve variants of the question (e.g., finding the lowest rating) without relying on seeing the exact problem beforehand.", + "why_maybe_unnecessary": "The student already has the exact answer in the existing exam snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q07", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q07", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[2, 4]", + "b": "[3, 4, 5]", + "c": "[4]", + "d": "[]" + }, + "correct": "c", + "explanation": "The list comprehension keeps values x from [1, 2, 3, 4, 5] only when x is even and greater than 2. The only value satisfying both conditions is 4.", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x for x in numbers if x % 2 == 0 and x > 2]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 7, + "question_summary": "What is the output of the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet contains the exact logic and explanation for the question, explicitly defining that 'x % 2 == 0' checks for even numbers and 'x > 2' is the second condition, leading to the answer '4'." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Direct match for the question logic and provides a clear linguistic explanation of the code's behavior." + }, + { + "item_id": "exam-trial_midterm-5-w2-loops", + "rationale": "Reinforces the meaning of the modulo operator (%) for parity checks (i % 2 == 0), which is a key part of the question." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Helps a student understand the logical 'and' operator used to combine the two conditions in the list comprehension." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Independently sufficient as it maps the exact code symbols to their logical meanings (even and greater than 2)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The dataset contains an identical question/explanation pair that removes all ambiguity for a non-technical user.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide perfect coverage because of the exact match. There is no need for further concept explanation as the direct answer is present.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:00:55Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q08", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q08", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "['a', 'bb', 'ccc']", + "b": "[1, 2, 3]", + "c": "[1, 'b', 3]", + "d": "['aa', 'bb', 'cc']" + }, + "correct": "a", + "explanation": "The loop iterates over pairs from zip(list1, list2) and multiplies each string by its matching integer, producing 'a', 'bb', and 'ccc'.", + "code_context": "list1 = [1, 2, 3]\nlist2 = ['a', 'b', 'c']\nresult = []\nfor item in zip(list1, list2):\n result.append(item[0] * item[1])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Demonstrates the basic structure of initializing an empty list, iterating through a collection with a for loop, and using .append() to build the result." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Shows the pattern of iterating over a list and appending results to a new list, which matches the code context structure." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Provides a basic example of the .append() method and list manipulation." + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Reinforces the concept of iterating through a list and appending specific elements to another list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Explains the loop and append logic." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Confirms the behavior of the append method." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While 'append' and 'for loops' are covered, no snippet explains the 'zip()' function or the behavior of multiplying a string by an integer ('a' * 1), which are the critical operations needed to determine the output.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current selection fails to explain Python-specific built-ins and operator overloading used in the question.", + "missing_concepts": [ + "zip() function behavior (pairing elements)", + "String multiplication by integer (repetition)", + "Tuple indexing (item[0], item[1])" + ], + "proposed_fix": "Add an AI-generated or source-exam snippet that demonstrates zip() pairing two lists and shows string-integer multiplication." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'The zip(a, b) function creates pairs of elements from two lists. item[0] refers to the first element in the pair, and item[1] to the second. Multiplying a string by an integer (e.g., \"a\" * 3) repeats the string that many times (\"aaa\").'", + "why_helpful": "Directly addresses the two most obscure parts of the question for a beginner: zip and string multiplication.", + "why_maybe_unnecessary": "Only if the student is expected to guess that 'multiplication' of a string and number behaves like repetition.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:01:12Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q09", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q09", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 1", + "question": "Suppose you have a list called mylist. You want to extract every fourth element starting from index 2 (inclusive) to the second-to-last index (inclusive) of that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45, 50]\n\nthen executing the following command:\nprint(subset)\n\nshould print:\n[20, 35]\n\nWhat should the blanks be filled with?", + "options": { + "a": "2:-1:3", + "b": "2:len(mylist)-1:3", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "c", + "explanation": "Both stop values exclude the last element while starting at index 2 and stepping by 3, so both expressions return [20, 35] for the example list.", + "code_context": "subset = mylist[___:___:___]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "It is the only snippet that explicitly demonstrates the slicing syntax with a step value (alphabet[1::2]), which helps the student recognize the pattern of using colons for slicing." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows basic slicing with a step parameter, though it omits the stop parameter." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Likely involves list manipulation or slicing to reverse/reorder a list, providing additional context for list operations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Establishes the [start:stop:step] syntax pattern." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the snippets explain the crucial rules needed for this question: 1) that the 'stop' index in Python slicing is exclusive (meaning to include the second-to-last item, one must stop at the last item), 2) the index mapping for -1 or len(mylist)-1, and 3) the explicit anatomical breakdown of [start:stop:step].", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets show syntax but not semantics. A student wouldn't know why '2:-1:3' works over other options because the concept of 'exclusive stop' is missing.", + "missing_concepts": [ + "Exclusive stop index in slicing", + "Negative indexing (-1 for last element)", + "Index-to-Position mapping (0-based indexing)" + ], + "proposed_fix": "Add a conceptual snippet or an exam question that explains the [start:stop:step] structure and the exclusive nature of the stop boundary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Slicing Cheatsheet' snippet: 'Python slicing follows the format list[start:stop:step]. Start is inclusive, stop is exclusive. Indices can be negative: -1 is the last element, -2 is second-to-last. Example: mylist[0:5:2] takes every 2nd element from index 0 up to (but not including) index 5.'", + "why_helpful": "This provides the exact mechanical rules required to solve any slicing problem without prior coding experience.", + "why_maybe_unnecessary": "If the goal is only to provide existing exam examples, but those examples currently lack explanatory power for this specific problem.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:01:34Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q10", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q10", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_2", + "question": "Suppose you have the following function, which takes a list of integers as an argument:\n\nWhat will be returned, if we call the function as follows:\nmain([0, 1, 2, 23, 24, 25])", + "options": { + "a": "'abcxyz'", + "b": "['a', 'b', 'c', 'x', 'y', 'z']", + "c": "'012232425'", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "The function walks through the alphabet with enumerate and appends each character whose index is present in the input list, giving a, b, c, x, y, and z.", + "code_context": "def main(x):\n alphabet = 'abcdefghijklmnopqrstuvwxyz'\n y = ''\n for index, character in enumerate(alphabet):\n if index in x:\n y += character\n return y" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "It defines the `alphabet` string variable in a loop context, which provides necessary context for the variable traced in the question, although it lacks the specific `enumerate` logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides the 'abcdefghijklmnopqrstuvwxyz' string definition used in the question." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Shows a function taking a list and iterating over it, which matches the structural pattern of the question's `main([0, 1...])` call." + }, + { + "item_id": "aiq-5", + "rationale": "Explicitly mentions a function taking a 'list of integers as an argument', reinforcing the input type used in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Context for the alphabet string." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Function and loop structure context." + }, + { + "item_id": "aiq-5", + "rationale": "List argument type context." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Provides a visual example of a 'list of integers' which helps a novice identify the input data structure." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The question's solution relies entirely on understanding the `enumerate()` function (which yields index-value pairs) and the `in` membership operator. Neither concept is explained or demonstrated in any of the candidate snippets, making the logic impossible to trace for someone with zero prior Python knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to explain the two core mechanics of the provided code: how `enumerate` works and how `in` checks for list membership.", + "missing_concepts": [ + "enumerate() behavior (index, value pairs)", + "membership operator 'in' for lists", + "string concatenation using +=" + ], + "proposed_fix": "Add a new snippet that specifically illustrates `enumerate()` being used on a string to access both position and character." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Using Enumerate' with code: `for index, char in enumerate('abc'): print(index, char)`. Explanation: 'enumerate' gives the position (0, 1, 2) and the character ('a', 'b', 'c') at the same time.", + "why_helpful": "Directly explains the 'untraceable' part of the question for a beginner.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for the 'in' operator: `if 5 in [1, 5, 10]: # This is True`. Explanation: The 'in' keyword checks if a value exists inside a list.", + "why_helpful": "Explains the conditional logic `if index in x` which determines which letters are appended.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:02:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q11", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q11", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_1", + "question": "Suppose you have a variable called x which contains a string as follows:\n\nx = 'Hello world'\n\nWhich of the following lines of code produce(s) 2 as an output?", + "options": { + "a": "print(x.count('o'))", + "b": "print(x.split(' ')[0].count('ll'))", + "c": "print(len(x)//5)", + "d": "All of the given options." + }, + "correct": "d", + "explanation": "The rendered solution page marks option D, indicating that the exam intends all three listed expressions to produce 2 for the given value of x.", + "code_context": "x = 'Hello world'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", + "rationale": "This snippet explicitly shows the use of 'string.count(letter)', which is essential for evaluating Option A and Option B in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", + "rationale": "Directly demonstrates the '.count()' method used on strings." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions the '.split()' method, which is necessary to understand how the string 'Hello world' is broken into parts in Option B." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows sequence indexing/slicing syntax 'alphabet[1::2]', which helps a beginner understand that square brackets '[]' are used to access elements of a string or list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", + "rationale": "Explains string counting logic." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides a reference to the split operation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Introduces the concept of bracket indexing." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While '.count()' and '.split()' are mentioned, none of the snippets explain the 'len()' function or the '//' (floor division) operator, making Option C impossible to evaluate for a student with zero prior knowledge. Additionally, the specific indexing '[0]' is not explicitly defined as 'take the first element'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets fail to cover built-in math operators and basic length functions required for string manipulation questions.", + "missing_concepts": [ + "len() function", + "// (floor division) operator", + "List/String indexing [0]" + ], + "proposed_fix": "Add a snippet from a 'Week 1' or 'Introduction' lecture/exam that covers basic arithmetic operators (including //) and fundamental built-in functions like len()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet demonstrating 'len()' on a string and the difference between '/' and '//' operators, as well as basic '[0]' indexing.", + "why_helpful": "This would allow a student to solve Option C (len and floor division) and Option B (indexing the result of a split).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:02:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q12", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q12", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_2", + "question": "You need to write a function called main which accepts a list of integers as an argument. The function should return a tuple of two integers, in which the first is the sum of the squares of all even numbers, and the second is the sum of the squares of all odd numbers.\n\nFor example, calling the function as:\nmain(1, 2, 3, 4)\nshould return:\n(20, 10)\n\nWhich of the following blocks of code fits with the rest of the program and will you give the intended output?", + "options": { + "a": "for i in args:\n if i % 2 == 0:\n total_even += i**2\n else:\n total_odd += i**2\n\nreturn (total_even, total_odd)", + "b": "for i in args:\n if i % 2 == 1:\n total_even += i\n else:\n total_odd += i\n\nreturn (total_even**2, total_odd**2)", + "c": "for i in args:\n if i % 2 == 0:\n total_even.append(i**2)\n else:\n total_odd.append(i**2)\n\nreturn (sum(total_even), sum(total_odd))", + "d": "All of the given code blocks work as intended." + }, + "correct": "a", + "explanation": "Option A directly accumulates the squares of even numbers and odd numbers into the two totals and returns them as the required tuple.", + "code_context": "def main(*args):\n total_even = 0\n total_odd = 0\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly connects 'flexible number of arguments' (which maps to the *args in the question) with the specific logic of filtering and summing even integers, providing the conceptual bridge for the student to identify the correct pattern." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers flexible arguments (*args) and the concept of processing even integers." + }, + { + "item_id": "aiq-5", + "rationale": "Demonstrates returning multiple aggregated values (sum, min, max) from a collection of integers, which helps the student understand returning a result container like a tuple or dictionary." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Shows basic loop structure and variable initialization (count = 0), which is critical for distinguishing between the += (Option A) and .append (Option C) choices based on the provided code context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains *args and even-number logic." + }, + { + "item_id": "aiq-5", + "rationale": "Shows returning a composite object with summed values." + }, + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "rationale": "Provides loop and accumulation syntax examples." + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Demonstrates the syntax for returning tuples (a, b), which is the required return type in the question." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover *args, loops, and the general concept of summing even numbers, they do not show the modulo operator (%) for parity or the exponentiation operator (**) for squaring. A student without Python knowledge might struggle to confirm that i % 2 == 0 means 'even' or that i**2 means 'squared' without those explicit definitions.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The primary gaps are the mathematical syntax for parity checking and exponentiation, as well as the explicit distinction between integer accumulation and list appending.", + "missing_concepts": [ + "Modulo operator (%) for even/odd checks", + "Exponentiation operator (**)", + "Returning a tuple (val1, val2)" + ], + "proposed_fix": "Add an AI-generated example or technical note that specifically demonstrates basic numeric operations (%, **, //) and the syntax for returning multiple values as a tuple." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new AI Example titled 'Numeric Operations and Tuples'. Content: 'To square a number use x**2. To check if a number is even, use num % 2 == 0. To return two values together, use return (value1, value2).'", + "why_helpful": "This directly addresses the missing syntactical knowledge required to verify the math in Option A vs Option B.", + "why_maybe_unnecessary": "The student might guess the meaning of % and ** from context or general programming knowledge, but for 'zero prior knowledge', it is essential.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:03:06Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q13", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q13", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 1", + "question": "You have the following objects loaded in Python:\nname = \"Alice\"\nage = 25\ncountry = \"the USA\"\n\nYou need to print the following string:\nMy name is Alice. I am 25 years old, and I am from the USA.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"My name is {0}. I am {2} years old, and I am from {1}.\".format(name, country, age)\nprint(message)", + "b": "message = f\"My name is {name}. I am {age} years old, and I am from {country}.\"\nprint(message)", + "c": "message = 'My name is ' + name + '. I am ' + str(age) + ' years old, and I am from ' + str(country) + '.'\nprint(message)", + "d": "All of the given options are correct." + }, + "correct": "d", + "explanation": "All three code variants produce the target sentence: one uses format, one uses an f-string, and one uses string concatenation with str(age) and str(country).", + "code_context": "name = \"Alice\"\nage = 25\ncountry = \"the USA\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is the only one that directly addresses the task of printing variables (Name, Grade) within a template string, which is the core concept of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Covers variable interpolation into a string template, similar to the f-string and .format() requirements." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Provides context for handling student names (strings) and grades (floats/numbers) within dictionaries, which mirrors the data types in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions 'formatting' strings, though it focuses on phone numbers rather than general interpolation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Closest available match for string templating." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the snippets explain the specific syntax for f-strings, the .format() method with positional indexing, or the requirement to use str() when concatenating integers with strings. A student with zero knowledge would not be able to determine that all three methods are valid based on the provided candidates.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate pool lacks a snippet that explicitly compares or defines the various string formatting techniques in Python.", + "missing_concepts": [ + "f-string syntax (f\"...\")", + ".format() method and positional placeholders ({0}, {1})", + "String concatenation with the '+' operator and type conversion using str()" + ], + "proposed_fix": "Add a dedicated 'String Formatting' snippet to the study database that shows examples of f-strings, .format(), and concatenation side-by-side." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Python String Formatting' that includes: 1. f-strings: f'Hello {name}', 2. .format(): 'Hello {}'.format(name), and 3. Concatenation: 'Hello ' + name + ' is ' + str(age).", + "why_helpful": "This would directly allow a student to recognize that all three options in the exam question perform the same task correctly.", + "why_maybe_unnecessary": "If the student has already seen these in basic lecture notes, but the goal is to help a student with 'zero prior knowledge' using only snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:03:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q14", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q14", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 2", + "question": "Suppose you have the following DataFrame called df, and assume that pandas is already imported:\n\n Player Goals Assists\n0 John 5 2\n1 Jane 3 6\n2 Alex 2 4\n\nAll of the following lines of code make the same selection, but one of the results has a different datatype. Which one?", + "options": { + "a": "df.loc[:, 'Goals']", + "b": "df['Goals']", + "c": "df.loc[[0, 1, 2], 'Goals']", + "d": "df.loc[:, ['Goals']]" + }, + "correct": "d", + "explanation": "The first three expressions return a Series, while selecting with a list of column names returns a one-column DataFrame instead.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions that specifying ['B'] as a list is used to create a 'new DataFrame', which provides a subtle hint that list-based selection results in a DataFrame structure." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Implicitly associates list-based column selection with returning a DataFrame." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Shows that selecting multiple columns (A, C, D) results in a DataFrame, reinforcing the idea of lists and DataFrames." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame structure, helping a student identify what 'df' looks like." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Only snippet that mentions the syntax of using a list for a single column to get a DataFrame." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explicitly explain that selecting a single column with a string returns a Series while a list returns a DataFrame. A student with zero knowledge would likely not infer the datatype difference from the 'new DataFrame' hint alone.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack an explicit explanation of pandas return types (Series vs. DataFrame) based on selection syntax (string vs. list).", + "missing_concepts": [ + "Pandas Series vs. DataFrame datatypes", + "Return types of .loc with single labels vs. lists", + "The 'double bracket' or list-indexing rule in pandas" + ], + "proposed_fix": "Add a snippet or detail rule that explicitly compares df['col'] (Series) and df[['col']] (DataFrame)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet from Week 5 lecture materials (Inspecting and Selecting Data) that states: 'When selecting a single column from a DataFrame: using a string label (e.g., df['A']) returns a Series, while using a list of one label (e.g., df[['A']]) returns a one-column DataFrame.'", + "why_helpful": "This directly addresses the core concept of the exam question regarding return types.", + "why_maybe_unnecessary": "If the goal is only to provide exam question examples, adding a theoretical rule might deviate from the current snippet style.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:03:48Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q15", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q15", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_3", + "question": "Which code segment gives the same output as the following:\n\ndate1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module.", + "options": { + "a": "print((datetime(2023, 5, 1) - datetime(2023, 6, 1)).days)", + "b": "print((datetime(2023, 6, 1) - datetime(2023, 1, 5)).days)", + "c": "print((datetime.strptime('2023-6-1', '%Y-%d-%m') - datetime.strptime('2023-5-1', '%Y-%d-%m')).days)", + "d": "print((datetime.strptime('2023-06-01', '%Y-%m-%d') - datetime.strptime('2023-05-01', '%Y-%m-%d')).days)" + }, + "correct": "d", + "explanation": "Option D parses ISO-style date strings using the matching '%Y-%m-%d' format and subtracts the May date from the June date, giving the same day difference as the original code.", + "code_context": "date1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the integer difference, which is the core logic of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explains the fundamental mechanic of datetime subtraction and the .days attribute used in the question." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Shows a concrete code example of datetime arithmetic and usage of the .days attribute." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Covers the subtraction and .days attribute logic." + }, + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Provides syntax for creating datetime objects and performing subtraction." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain datetime arithmetic and the .days attribute. However, they do not explain the strptime/strftime format codes (%Y, %m, %d, etc.), making it impossible for a student without prior knowledge to determine if the parsing in Option D matches the input strings.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The main gap is the lack of information regarding string-to-date parsing (strptime) and the specific format codes needed to interpret the strings '2023-06-01' vs '2023-6-1'.", + "missing_concepts": [ + "strptime", + "strftime", + "datetime format codes (%Y, %m, %d)" + ], + "proposed_fix": "Add a reference snippet that lists common datetime format codes and demonstrates how strptime parses a string into a datetime object." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Formatting Cheatsheet' snippet. It should show: %Y (Year 2023), %m (Month 01-12), %d (Day 01-31), %H, %M, %S. Include an example: datetime.strptime('2023-06-01', '%Y-%m-%d').", + "why_helpful": "This allows students to translate the strings in the options into actual dates and compare them to the original code's dates.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:04:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q16", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q16", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Easy_2", + "question": "You have the following definition of a class called Flight. What would be the output if we execute the following statements?", + "options": { + "a": "'long'\n'cheap'", + "b": "'short'\n'expensive'", + "c": "'long'\n'expensive'", + "d": "'short'\n'cheap'" + }, + "correct": "a", + "explanation": "The first condition sets the KLM flight to Singapore to duration 'long', and the second condition sets the EasyJet flight to Spain to price 'cheap', so the two prints output 'long' and then 'cheap'.", + "code_context": "class Flight:\n def __init__(self, airline, destination):\n self.airline = airline\n self.destination = destination\n\n if self.airline == 'KLM' and self.destination == 'Singapore':\n self.duration = 'long'\n self.price = 'expensive'\n\n if self.airline == 'EasyJet' and self.destination == 'Spain':\n self.duration = 'short'\n self.price = 'cheap'\n\nprint(Flight('KLM', 'Singapore').duration)\nprint(Flight('EasyJet', 'Spain').price)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-06b21ad349", + "rationale": "Explains the core concept of the __init__ method as a constructor that initializes attributes and provides a direct syntax example (class Car) that maps to the question's structure." + }, + "top_three_snippets": [ + { + "item_id": "ks-06b21ad349", + "rationale": "Provides the fundamental explanation of class definitions, the constructor, and attribute assignment using 'self'." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Explains logical operators like '==', '!=', and 'and', which are critical for evaluating the if-statements inside the Flight class constructor." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides a secondary example of defining a class with multiple attributes, reinforcing the pattern of initializing state during object construction." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-06b21ad349", + "rationale": "Covers OOP structure and attribute assignment." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Covers string comparison and logical conjunction logic used in the conditions." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets explain both the OOP structure (how data is stored in attributes during initialization) and the logic gates (how the 'if' conditions evaluate). A student can trace 'KLM' and 'Singapore' to the first block and 'EasyJet' and 'Spain' to the second.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is fully coverable, the snippets don't explicitly show an example of conditional attribute assignment (if/else) inside a constructor.", + "missing_concepts": [ + "Conditional attribute assignment within __init__" + ], + "proposed_fix": "Add a lecture snippet or exam question that specifically demonstrates setting different attribute values based on constructor input parameters." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing a class where attributes are set conditionally, e.g., 'if age > 18: self.status = \"adult\" else: self.status = \"minor\"'.", + "why_helpful": "It directly mirrors the 'logic-heavy' constructor pattern seen in this exam question, reducing the mental leap for a novice.", + "why_maybe_unnecessary": "Basic OOP and Basic Conditions are present, and their combination is logically intuitive.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:04:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q17", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q17", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "6-string - operations - 1", + "question": "Consider the following code snippet. Which operation in the code snippet contains an error?", + "options": { + "a": "Operation 1", + "b": "Operation 2", + "c": "Operation 3", + "d": "None of the operations contains an error." + }, + "correct": "b", + "explanation": "Operation 2 is incorrect because join should be called as the separator string's method with a single iterable argument, for example '-'.join(word_list).", + "code_context": "text = \"The universe is vast and full of mysteries!\"\n\n# Operation 1:\nword_list = []\nfor word in text.split():\n word_list.append(word[::-1])\n\n# Operation 2:\njoined_text = ' '.join(word_list, '-')\n\n# Operation 3:\nreplaced_text = text.replace(\"mysteries\", \"secrets\")" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Explicitly mentions the .replace() method and its behavior, helping the student verify that Operation 3 is a valid Python string method." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Validates the use of the .replace() method seen in Operation 3." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates string slicing syntax (e.g., [1::2]), which helps a student understand the word[::-1] syntax used in Operation 1." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions the .split() method, allowing the student to recognize it as a standard string operation used in Operation 1." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Confirms .replace() syntax." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Confirms slicing syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Confirms .split() syntax." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Confirms that .append() is a valid list method, validating the logic in Operation 1." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide enough information to validate Operation 1 (split, append, slicing) and Operation 3 (replace). By process of elimination, a student might identify Operation 2 as the error. however, no snippet explicitly shows the correct syntax for the .join() method (which takes only one argument), meaning the student cannot 'prove' the error in Operation 2 directly from the provided text.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is no reference for the .join() method's syntax, specifically that it is called on the separator and takes exactly one iterable argument.", + "missing_concepts": [ + "str.join(iterable) syntax and argument count" + ], + "proposed_fix": "Add a snippet or documentation item that demonstrates joining a list of strings into a single string using a separator." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: separator = '-'; words = ['a', 'b', 'c']; result = separator.join(words).", + "why_helpful": "It would allow the student to see that .join() is called on the string separator and takes only the list as an argument, making the error in ' '.join(word_list, '-') (two arguments) obvious.", + "why_maybe_unnecessary": "Process of elimination might be sufficient for an exam setting if all other operations are clearly validated.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:04:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q18", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q18", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "6-strings - find - 2", + "question": "Suppose you have the following variables called sentence1 and sentence2 which contain strings. The sentences contain names, but they are not properly capitalized. You want to create a new string object called paragraph, with the proper nouns capitalized in the two sentences and the two sentences connected into one big string.\n\nThat is, if we execute the following line of code:\nprint(paragraph)\nthe output should be:\n\"Harry, Ron, and Hermione walked through the halls of Hogwarts; their footsteps echoing off the stone walls.\nThe Marauder's map in Harry's hands revealed the secret passageways and hidden rooms of the castle.\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor name in names:\n sentence1[sentence1.find(name)] = name.capitalize()\n sentence2[sentence2.find(name)] = name.capitalize()\nparagraph = sentence1 + \" \" + sentence2", + "b": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor word, name in zip(sentence1, names):\n if word == name:\n sentence1 = sentence1.replace(word, name.capitalize())\nfor word, name in zip(sentence2, names):\n if word == name:\n sentence2 = sentence2.replace(word, name.capitalize())\nparagraph = sentence1 + \" \" + sentence2", + "c": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nnew1 = ' '.join([word.capitalize() if word in names else word for word in sentence1])\nnew2 = ' '.join([word.capitalize() if word in names else word for word in sentence2])\nparagraph = new1 + \" \" + new2", + "d": "for word in ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']:\n sentence1 = sentence1.replace(word, word.capitalize())\n sentence2 = sentence2.replace(word, word.capitalize())\nparagraph = sentence1 + \" \" + sentence2" + }, + "correct": "d", + "explanation": "Option D correctly replaces each lowercase proper noun with its capitalized version in both strings and then concatenates the two sentences into paragraph.", + "code_context": "sentence1 = \"harry, ron, and hermione walked through the halls of hogwarts; their footsteps echoing off the stone walls.\"\nsentence2 = \"The marauder's map in harry's hands revealed the secret passageways and hidden rooms of the castle.\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the most relevant snippet as it explicitly deals with string manipulation (splitting and mapping) in a context of cleaning up names, which aligns with the question's goal of formatting names within strings." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides context for string transformations and handling name/location data." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions phone number formatting where digits are separated by characters, implying string cleaning or replacement logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Discusses casing (upper/lower case) in the context of anagrams, which highlights the importance of case sensitivity mentioned in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Closest match for string transformation." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Context for string formatting/cleanup." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the provided snippets define or demonstrate the '.replace()' method, the '.capitalize()' method, or string concatenation using the '+' operator. While some snippets mention strings and casing, they do not provide the syntactical proof needed for a student with zero prior knowledge to distinguish between the options (e.g., knowing that strings are immutable and thus Option A is invalid, or that '.replace()' exists and is the correct tool in Option D).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus on complex structures (OOP, Dictionaries, Pandas) but skip the fundamental string methods required for this specific question.", + "missing_concepts": [ + "str.replace()", + "str.capitalize()", + "String concatenation (+)", + "String immutability (to rule out item assignment in Option A)" + ], + "proposed_fix": "Add a snippet from the 'Week 1 - Objects and Names' or 'Week 4 - String Fundamentals' lecture that specifically lists common string methods like replace, capitalize, upper, and lower, along with concatenation examples." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new 'String Operations' snippet that covers: 1. str.replace(old, new) for substitution. 2. str.capitalize() and str.title() for casing. 3. '+' for joining strings. 4. An explicit note that strings cannot be modified in-place (no sentence[i] = 'X').", + "why_helpful": "This question tests basic string method knowledge. Without a reference to these specific methods, a student cannot confidently select 'd' over 'a' or 'c'.", + "why_maybe_unnecessary": "It is only unnecessary if the student has access to the full Python documentation or has already memorized basic string syntax.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:05:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q19", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q19", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - hard - 2", + "question": "Consider the following pandas DataFrame called df, and assume that Pandas is already imported.\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Name_Length that contains the length of each person's name\n- Operation 2: Replace all occurrences of the occupation 'Engineer' with 'Software Developer'\n- Operation 3: Extract the last two characters of each person's name and store them in a new column called Name_Suffix\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df['Name_Length'] = df['Name'].map(lambda x: len(x))\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:])", + "b": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].lambda x: x[-2:]", + "c": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[:-2])", + "d": "df['Name_Length'] = df['Name'].map(len)\ndf['Occupation'] = df['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:-1])" + }, + "correct": "a", + "explanation": "Option A correctly maps each name to its length, replaces only the Engineer entries, and slices the final two characters with x[-2:].", + "code_context": "Name Age Occupation\n0 John 25 Student\n1 Jane 30 Engineer\n2 Alex 35 Scientist\n3 Lisa 40 Doctor\n4 Mark 28 Architect" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains the .map() method for applying functions to Series, which is the primary mechanism used in the correct answer for operations 1 and 3." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly explains how to use .map() to transform Series values using functions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the basic syntax for creating a new column in a DataFrame (df['C'] = ...), essential for all three operations." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Reinforces the concept of calculating string lengths within a collection, which relates to the Name_Length requirement." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Covers the map() method usage." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers new column assignment." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides context for string length logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain how to create new columns and use the .map() method. However, they do not explain 'list comprehension' (used in Operation 2) or 'negative indexing string slicing' (used in Operation 3). A student without prior knowledge would see the syntax in Option A but wouldn't know why [-2:] is correct versus other slices.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets cover Pandas structural basics but miss core Pythonic transformations used in 'hard' Pandas questions.", + "missing_concepts": [ + "list comprehension for conditional replacement in columns", + "negative indexing for string slicing (e.g., [-2:])", + "lambda function syntax details" + ], + "proposed_fix": "Add a snippet specifically demonstrating string manipulation and conditional logic (ternary operators) within Pandas transformations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet illustrating: 1) Using .map(lambda x: x[-n:]) to extract suffixes. 2) Using list comprehension [value if condition else other for x in series] to replace specific values in a column. 3) Comparing .map(len) vs map(lambda x: len(x)).", + "why_helpful": "This would directly address the 'hard' components of the question (Operations 2 and 3) which are currently unsupported by the recommended snippets.", + "why_maybe_unnecessary": "Basic pattern matching might lead a student to Option A, but they wouldn't understand 'why' it works without these concepts.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:05:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q20", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q20", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - lambda - 2", + "question": "What will be printed by the following code?", + "options": { + "a": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 72 13\n1 B 45 19", + "b": "Product Units Price\n1 B 50 19\n0 A 100 10\n3 D 80 13\n2 C 200 15", + "c": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 80 13\n1 B 50 19", + "d": "Product Units Price\n2 C 200 15\n3 D 80 13\n0 A 100 10\n1 B 50 19" + }, + "correct": "c", + "explanation": "UnitsCorrected and Revenue are used only for sorting; df1 keeps the original Units and Price columns, and sorting by descending revenue gives rows C, A, D, B.", + "code_context": "import pandas as pd\nd = {'Product':['A', 'B', 'C', 'D'], 'Units':[100, 50, 200, 80], 'Price':[10, 19, 15, 13]}\ndf = pd.DataFrame(d)\ndf.loc[:, 'UnitsCorrected'] = df.loc[:, 'Units'].map(lambda x: 0.9*x if x < 100 else x)\ndf.loc[:, 'Revenue'] = df.loc[:, 'UnitsCorrected'] * df.loc[:, 'Price']\ndf = df.sort_values(by='Revenue', ascending=False)\ndf1 = df.loc[:, ['Product', 'Units', 'Price']]\nprint(df1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "It explicitly mentions the .map() method and applying functions to Series elements, which is the most complex part of the code (the lambda mapping)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains .map() for element-wise function application." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Explains vectorized operations (adding columns) which maps to the Revenue calculation." + }, + { + "item_id": "cs-b46633d18d", + "rationale": "Shows the syntax for creating a DataFrame from a dictionary, which is the first step of the problem." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Covers .map() usage." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers column creation and vectorized math." + }, + { + "item_id": "cs-b46633d18d", + "rationale": "Covers DataFrame initialization." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover DataFrame creation, column math, and .map(), they do not explain the 'lambda' syntax itself or the 'sort_values' method. A student wouldn't know how to evaluate the conditional '0.9*x if x < 100 else x' inside the lambda or what 'ascending=False' does to the order.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide a foundation for Pandas structure but fail to explain functional programming constructs (lambda) and data organization methods (sorting).", + "missing_concepts": [ + "Lambda functions with conditional logic (if-else ternary)", + "df.sort_values() and the ascending parameter", + "Projecting multiple columns using a list inside .loc" + ], + "proposed_fix": "Add a snippet demonstrating df.sort_values(by=..., ascending=False) and a basic explanation of lambda x: expression." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: df = df.sort_values(by='col', ascending=False) with a comment: '# Sorts the table by the values in \"col\", from highest to lowest'.", + "why_helpful": "Essential for determining which rows appear first in the final output (Product C then A).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining lambda: 'df[\"A\"].map(lambda x: x*2) means apply the rule \"take x and return x times 2\" to every row in column A'.", + "why_helpful": "The most difficult syntactic hurdle for a zero-knowledge student in this specific problem.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:05:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q21", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q21", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_2", + "question": "You have the following definition for a class called Calendar.\n\nThe method check_overlap() should return True if there are two overlapping events and False if the two events are not overlapping.\n\nFor example, if we have the following Calendar objects:\nevent1 = Calendar('Coffee meeting', '01-06-2023 9:30', 20)\nevent2 = Calendar('Writing session', '01-06-2023 10:00', 150)\nevent3 = Calendar('Lunch meeting', '01-06-2023 12:00', 45)\n\nthe following command should return False:\nprint(event1.check_overlap(event2))\n\nand the following command returns True:\nprint(event2.check_overlap(event3))\n\nDoes the code segment given above do what you want? If not, then why not?\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the condition provided after the return keyword is incorrect.", + "c": "This code segment does not work because the syntax to parse the input string to create a datetime object is incorrect.", + "d": "This code segment does not work because the __init__ method needs 4 parameters and only 3 arguments are passed." + }, + "correct": "a", + "explanation": "The datetime format string matches the input values, timedelta(minutes=length) creates the correct end time, and the overlap condition correctly detects whether two intervals intersect.", + "code_context": "from datetime import datetime, timedelta\n\nclass Calendar():\n def __init__(self, event, start, length):\n self.event = event\n self.start = datetime.strptime(start, '%d-%m-%Y %H:%M')\n self.end = self.start + timedelta(minutes=length)\n def check_overlap(self, other):\n return self.start < other.end and self.end > other.start" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Helps clarify the syntax and logic of a method ('compare') that takes 'self' and 'another' object as arguments, which is structurally identical to the 'check_overlap(self, other)' method in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates how classes use methods to compare one instance to another ('other'), supporting the logic in check_overlap." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides an example of the __init__ constructor and attribute initialization, helping verify the class structure and constructor argument counts." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Explains method-based comparisons between class instances." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Validates the standard syntax for Python class initialization (__init__)." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets explain general OOP structure (classes and methods), none of the available snippets mention the 'datetime' module, 'strptime' formatting strings, or 'timedelta' arithmetic. A student with zero knowledge cannot verify if '%d-%m-%Y %H:%M' correctly parses '01-06-2023 9:30' or if the interval overlap logic is correct without a datetime-specific reference.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of 'datetime' and 'timedelta' documentation or examples in the recommended snippets.", + "missing_concepts": [ + "datetime.strptime", + "Time formatting codes (%d, %m, %Y, %H, %M)", + "timedelta arithmetic", + "Interval overlap boolean logic" + ], + "proposed_fix": "Add a snippet or documentation entry specifically for the datetime library that shows how to parse strings and calculate durations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: 'from datetime import datetime, timedelta; dt = datetime.strptime(\"23-03-2026 14:00\", \"%d-%m-%Y %H:%M\"); end = dt + timedelta(minutes=30)'.", + "why_helpful": "This would allow a student to verify the syntax for parsing (strptime) and time addition (timedelta) used in the question.", + "why_maybe_unnecessary": "The question hint provides some info on timedelta, but not on strptime or format strings.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining the logic for checking if two time intervals (start1, end1) and (start2, end2) overlap: 'start1 < end2 and end1 > start2'.", + "why_helpful": "This is a common exam pattern that is difficult to deduce with zero prior logic/programming knowledge.", + "why_maybe_unnecessary": "Some students might be able to figure this out logically if they draw it, but it's a high cognitive load.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:06:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q22", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q22", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_1", + "question": "You want to create a DataFrame called df that has the following format:\n\n Day Month Year\n01-01-23 1 1 2023\n08-01-23 8 1 2023\n15-01-23 15 1 2023\n22-01-23 22 1 2023\n29-01-23 29 1 2023\n\nWhich of the following code segments achieves what you want?\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module, as well as the pandas module (via: import pandas as pd).\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "dates = [(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=[date.strftime('%d-%m-%y') for date in dates])", + "b": "dates = [(datetime(2023, 1, 1) + timedelta(days=7*i)).strftime('%d-%m-%y') for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=dates)", + "c": "day = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).day for i in range(5)])\nmonth = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).month for i in range(5)])\nyear = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).year for i in range(5)])\ndf = pd.DataFrame(data=[day, month, year])", + "d": "df = pd.DataFrame(index=[(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)],\n {'Day': [date.days for date in index],\n 'Month': [date.months for date in index],\n 'Year': [date.year for date in index]})" + }, + "correct": "a", + "explanation": "Option A keeps real datetime objects long enough to derive day, month, year, and then formats those dates into the desired string index for the DataFrame.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that introduces the relationship between 'datetime' and 'timedelta' objects, which is the core logic required to generate the sequence of dates in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Introduces the datetime and timedelta classes and mentions accessing attributes like '.days' on timedelta objects." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Illustrates how DataFrames use columns (Series) of data, which helps a student understand the 'data' dictionary structure used in options A and B." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "Shows list and variable structures, assisting in the interpretation of the list comprehensions used to build the 'dates' list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Essential for understanding the library classes mentioned in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Necessary to understand the construction of a DataFrame from a dictionary." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the question provides a hint for timedelta parameters, the candidate snippets fail to explain: 1) datetime attributes (.day, .month, .year), 2) the .strftime() method, and 3) that .strftime() returns a string. Without this, a student cannot know that Option B is invalid because it tries to call .day on a string, nor can they confirm Option A is correct for formatting the index.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide the basic 'container' (Pandas) and 'type' (Datetime) context, but lack the specific 'member' (attributes/methods) knowledge required for this 'Hard' level question.", + "missing_concepts": [ + "datetime object attributes: .day, .month, .year", + "datetime.strftime() method and common format codes (e.g., %d, %m, %y)", + "The fact that strftime returns a string (type conversion)" + ], + "proposed_fix": "Add a snippet or detail rule explaining how to extract components from a datetime object and how to format it as a string for display." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Datetime Attribute Extraction and Formatting'. Content: 'Given dt = datetime(2023, 1, 1), use dt.day, dt.month, and dt.year to get integers. Use dt.strftime(\"%d-%m-%y\") to create a formatted string like \"01-01-23\".'", + "why_helpful": "Directly provides the information needed to distinguish between the datetime object (needed for attributes) and the formatted string (needed for the index).", + "why_maybe_unnecessary": "The student might guess based on the intuitive names of '.day' and '.year', but they wouldn't know 'strftime' or how it differs from a raw object.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:06:40Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q23", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q23", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Function_3", + "question": "You have the following definition of a class called Pack.\n\nYou want to add to this class a method called fitting() that calculates how many times another object of the class Pack would fit inside this object.\nThe method should return the number of times these other objects would fit completely in this object, and the final value.\nThe final value is the sum of all values of all objects that fit in it, plus the value of the carrying object self.\n\nFor example, if we execute the lines of code:\nbackpack = Pack(size=15, value=20)\nbook = Pack(size=4, value=10)\nbackpack.fitting(book)\n\nthe output should be:\nAmount: 3. Value: 50.\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def fitting(self, other):\n if self.size > other.size:\n self.total = (self.size // other.size) * other.value + self.value\n return f'Amount: {self.size // other.size}. Value: {self.total}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "b": "def fitting(self, other):\n if self.size > other.size:\n return f'Amount: {self.size // other.size}. Value: {other.value * other.size}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "c": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return f'Amount: {self.amount}. Value: {self.total}.'", + "d": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return 'Amount: {}. Value: {}.'.format(self.amount, self.value if self.size > other.size else self.total)" + }, + "correct": "a", + "explanation": "Option A uses integer floor division to count only full fits, adds the carried items' value plus self.value, and returns zero items with self.value when the other object does not fit.", + "code_context": "class Pack:\n def __init__(self, size, value = 0):\n self.size = size\n self.value = value\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet is critical because it demonstrates writing a method that compares 'self' to 'another' object of the same class, showing the exact attribute access pattern (e.g., self.score vs other.score) required by the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how methods interact with other instances of the same class and use comparison logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational context for class definition and attribute initialization (self.name, self.mode)." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Demonstrates the 'if/else' conditional structure needed to handle the two different return cases in the fitting() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Method-level attribute comparison logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Class/attribute boilerplate." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Conditional branching logic." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows string formatting with placeholders, which helps decode the f-string/format syntax in the options." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "Existing snippets cover class structure, method definitions, attribute access on 'self' vs 'other', and conditionals. However, no snippet explains the difference between floor division (//) and standard division (/), which is the primary technical distinction between the correct option A and the incorrect options C/D.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student can figure out the OOP structure and logic flow from the snippets, but might struggle to choose between (/) and (//) without an arithmetic operator reference.", + "missing_concepts": [ + "Integer/Floor division (//) vs Floating point division (/)", + "F-string syntax specifically" + ], + "proposed_fix": "Add an AI-generated or source-based snippet covering basic arithmetic operators, emphasizing that // is used for 'fitting' or 'counting whole units'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A reference card for Python Arithmetic Operators: + (addition), - (subtraction), * (multiplication), / (division), // (floor division/integer), % (modulo). Include an example like '15 // 4 = 3 (fits 3 times)'.", + "why_helpful": "The question hinges on calculating how many times something 'fits completely', which requires // instead of /.", + "why_maybe_unnecessary": "Students might infer // is 'special' for integers given the context 'Amount: 3' in the example output.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:06:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:introduction-to-python-trial-final-exam-solutions-py22-q24", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q24", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Hard_1", + "question": "You have the following definition for a class called Piece.\n\nAnd the creation of three objects with the help of the class definition:\na = Piece(diagonal=True, straight=False, initial_position=(0, 0))\nb = Piece(diagonal=False, straight=True, initial_position=(4, 3))\nc = Piece(diagonal=True, straight=True, initial_position=(9, 6))\n\nIf we run the following statements:\nprint(a.check_move((4, 4)))\nprint(b.check_move((5, 5)))\nprint(c.check_move((6, 6)))\n\nThis will print 3 Boolean values. Of these values, how many times will this be True?", + "options": { + "a": "0", + "b": "1", + "c": "2", + "d": "3" + }, + "correct": "b", + "explanation": "The first move fails because the row and column differences are both 4, which is above the allowed maximum of 3. The second fails because a straight-only piece cannot move diagonally. The third succeeds because a piece that can move straight and diagonally may move along the same column within 3 steps, so exactly one result is True.", + "code_context": "class Piece:\n def __init__(self, diagonal, straight, initial_position):\n self.diagonal = diagonal\n self.straight = straight\n self.initial_position = initial_position\n\n def check_move(self, target_position):\n self.target_position = target_position\n self.row_diff = self.target_position[0] - self.initial_position[0]\n if abs(self.row_diff) > 3:\n return False\n self.col_diff = self.target_position[1] - self.initial_position[1]\n if abs(self.col_diff) > 3:\n return False\n\n if self.diagonal and (not self.straight):\n return abs(self.row_diff) == abs(self.col_diff)\n if self.straight and (not self.diagonal):\n return abs(self.row_diff) == 0 or abs(self.col_diff) == 0\n if self.straight and self.diagonal:\n return (abs(self.row_diff) == abs(self.col_diff)) or (abs(self.row_diff) == 0 or abs(self.col_diff) == 0)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the essential syntax for defining a class, using __init__, and setting attributes, which mirrors the structure of the Piece class in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Explains the foundational OOP concepts of class definition and attribute initialization used in the question's code." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Clarifies logical operators (and, or, !=) and type conversion (int), which are critical for evaluating the Boolean expressions in the check_move method." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows a method (compare) inside a class that performs logic on attributes, helping a student understand how check_move operates on the Piece object." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Covers class/attribute basics." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Covers logical evaluation." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Covers method logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Though about Pandas, it shows coordinate-like indexing (rows/cols) which might help a student infer how tuple indexing works, though it's a weak link." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain how classes are built and how logical 'and/or' works. However, there is no snippet explaining the 'abs()' function or how to index into a tuple/list (e.g., target_position[0]), both of which are central to calculating the row and column differences in this specific problem.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "A student with zero knowledge would struggle with the mathematical operations and data structure access inside the method.", + "missing_concepts": [ + "abs() function for absolute values", + "Indexing into tuples/lists (e.g., sequence[0])", + "The 'self' keyword and attribute access syntax" + ], + "proposed_fix": "Add a snippet or reference explaining basic built-in functions like abs() and how to access elements in a coordinate pair (tuple indexing)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining 'self' and tuple indexing. Example: 'In Python classes, self.attribute refers to the data stored in that object. If a variable represents a position like (row, col), position[0] gets the row and position[1] gets the col.'", + "why_helpful": "The question relies heavily on understanding that initial_position[0] is a number being subtracted from target_position[0]. Without knowing what the brackets do, the math is impossible to trace.", + "why_maybe_unnecessary": "Some students might guess indexing based on other languages, but it's risky for zero-knowledge users.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for common built-in functions: 'abs(x) returns the absolute (positive) value of a number. For example, abs(-3) is 3.'", + "why_helpful": "The logic for distance (row_diff > 3) and diagonal movement (abs(row_diff) == abs(col_diff)) requires knowing what abs() does.", + "why_maybe_unnecessary": "Abs is common in math, but its specific Python syntax should be confirmed.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:07:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round1/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json b/data/vision_exam_pipeline/work_packets/evaluations/round1/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json new file mode 100644 index 0000000..29848bb --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round1/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json @@ -0,0 +1,2102 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 357615", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "All three expressions evaluate to True: 2 * 3 = 6 equals x[2][1], 3 + 5 = 8 equals x[-1][1], and 7 - 5 = 2 equals x[0][1].", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you have a list called x containing tuples, where x = [(1, 2), (3, 4), (5, 6), (7, 8)] Which of the following lines of code will print True?", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This snippet is a verbatim match for the question and provides the step-by-step arithmetic evaluation for each option (e.g., explaining that Option A evaluates to 2 * 3 == 6)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Verbatim match with explicit evaluation logic for the expressions." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Another verbatim match that confirms all options evaluate to True, providing redundant but helpful verification." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This single snippet provides the full answer and the logic required to verify it." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact question and the full evaluation of the code logic, making it trivial to answer even without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the specific answer is provided, there is no general explanation of how nested indexing or negative indexing works for a student to apply to similar but different problems.", + "missing_concepts": [ + "Negative indexing (e.g., x[-1] refers to the last element)", + "Nested indexing (e.g., x[i][j] accesses element j within the i-th sub-element)" + ], + "proposed_fix": "Add a theoretical reference card or key point snippet explaining Python indexing rules (0-based, negative indexing, and multi-dimensional access)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Python List & Tuple Indexing. 1. Indexing starts at 0. 2. Negative indices count from the end (-1 is the last item, -2 is second to last). 3. For nested structures like x = [(a, b)], x[0][1] accesses the second item of the first tuple.", + "why_helpful": "This would allow the student to understand *why* x[0][1] is 2, rather than just relying on a matched example.", + "why_maybe_unnecessary": "The exact question already exists in the exam bank snippets, so for this specific exam, the student can just match the pattern.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:07:37Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q02", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q02", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 357607", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "The function called power should not return the string 'The result of {} ** {} is: {}'.format(num, factor, result), but the value of result.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "Result is a local name that cannot be referenced outside of the function power." + }, + "correct": "d", + "explanation": "`result` is defined inside the function `power`, so it is local to that function. The statement `print(result)` outside the function therefore raises a name error because `result` is not defined there.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}'.format(num, factor, result)\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "This snippet contains a nearly identical question and provides a clear explanation that variables defined inside a function are local and cannot be accessed in the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a direct example of the error in the question, identifying 'result' as a local variable." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the fundamental concept of local and global scope, defining local names as those assigned inside a function." + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "Explicitly states that 'local names are gone after function ends', which directly explains why the print(result) call fails." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the theoretical foundation for local names and scope." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Applies the theory to the exact code structure presented in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets provide both the theoretical definition of local scope and a direct application of that concept to a code snippet identical to the one in the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets cover the topic comprehensively.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:07:51Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 355235", + "question": "What will be printed by the following code segment?", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[]", + "d": "[None]" + }, + "correct": "d", + "explanation": "The code appends list-typed elements to `y`, but the return expression uses `append`, which itself returns `None`. The page marks option D as correct, so the intended evaluated output is `[None]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n\n return [y.append(i)]\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What will be printed by the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "This snippet explains the logic of `type(i) == type(x)`, helping the student understand that the loop identifies elements whose type matches the container (i.e., identifying lists within the list)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Explains the type-checking loop logic which is identical to the first half of the question code." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows the `.append()` method in use, which is necessary for recognizing what the code is attempting to do with the list." + }, + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "rationale": "Includes 'None' as a possible output option (Option D), which aligns with the correct answer in the target question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Covers the type-comparison logic used in the filter loop." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows basic list modification methods like append." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets perfectly explain the type-filtering logic (identifying the empty list `[]`). However, no snippet explains that the `.append()` method returns `None`. A zero-knowledge student would likely conclude the answer is `[[]]` (Option B) because they understand the filter, but miss the 'trick' where the return statement wraps the result of an `append` call.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets cover loop logic and type identification but miss critical technical details regarding method return values and post-loop variable scope.", + "missing_concepts": [ + "The list.append() method modifies the list in-place and returns None.", + "The loop variable (i) remains accessible and holds its last value after a for-loop completes." + ], + "proposed_fix": "Add a snippet or documentation item explaining that in-place methods (append, remove, sort, extend) return None, specifically contrasting `return mylist` with `return mylist.append(x)`." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'List Methods and Return Values': Common list methods like .append(), .remove(), and .sort() perform actions 'in-place'. This means they change the list but return the value None. If you see code like 'print(mylist.append(5))' or 'return [mylist.append(5)]', the output will be None or [None].", + "why_helpful": "This addresses the specific 'trap' in the question that separates students who understand loop logic from those who understand Python's method return conventions.", + "why_maybe_unnecessary": "It is a very specific technical detail, but it is a recurring theme in 'Return Behavior' exam questions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:08:19Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "function defaults and loops", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "This code produces an error as there is a missing argument when calling main.", + "b": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10']", + "c": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')", + "d": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10',\n '1 * 11 = 11']" + }, + "correct": "b", + "explanation": "`main(1)` is valid because `y` has default value `11`. The loop starts at `i = 1` and runs while `i < y`, so it appends the multiplication strings for 1 through 10 and stops before 11.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nprint(main(1))" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "Suppose you have the following function, which takes two integers as arguments: What will be printed by the following line of code: print(main(1))", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ], + "evidence_topics": [ + "Loops" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This is an identical question with an explanation that explicitly states y=11 is a default argument and the loop runs from 1 to 10." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Directly answers the specific question and explains the default argument and loop logic." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Another direct match for the question, reinforcing the behavior of the default argument y=11." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Provides a clear example of how multiple default arguments work and how they are overridden or kept when calling the function." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Provides the exact solution and logic for the while loop and default value." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question and explanation are present in the provided snippets, making the answer directly accessible.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets provide a 1:1 match for the question, so there are no functional gaps for this specific test case.", + "missing_concepts": [], + "proposed_fix": "No fix required as the exact content is available." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:08:32Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "list slicing and sets", + "question": "Suppose you have a list called x, where:\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Option A removes duplicates and sorts descending, which gives `[5, 4, 3, 2, 1]`. Option B takes every second element from the end of the symmetric list and also prints `[5, 4, 3, 2, 1]`.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n# target output:\n# [5, 4, 3, 2, 1]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "Suppose you have a list called x, where: Which of the following code segments will print the following list? [5, 4, 3, 2, 1]", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet contains the exact question and a clear explanation of both Option A (set/sorting) and Option B (slicing), though the text for Option B is slightly truncated." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Identical question match; explains set(x) for uniqueness and reverse sorting." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Another identical match providing a slightly different wording for the explanation of Option A." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides additional context for list slicing syntax [start:stop:step], which helps decode the [::-2] logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Contains the literal question and answer logic for both methods being tested." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets provide the exact question and explain why both segments produce the desired output, specifically mentioning set-based deduplication and reverse-step slicing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the direct answer, but the explanation for the slicing logic ([::-2]) is cut off in the available search text.", + "missing_concepts": [ + "Negative step slicing mechanics (stepping backwards)" + ], + "proposed_fix": "Ensure the explanation for slicing in the snippet is fully captured to clarify that -2 steps backwards by two elements." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "proposal": "Update search_text to include: 'Option B uses slicing [::-2] to step backwards through the list by 2, which skips the duplicates and reverses the order.'", + "why_helpful": "It clarifies the 'magic' of the slicing syntax which is currently truncated in the snippet.", + "why_maybe_unnecessary": "The student might infer the result because it is a direct match of a known exam question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:08:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "keyword arguments", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "To sum the numeric keyword-argument values, the function must iterate over `kwargs.values()`. Option A adds the string keys instead of the prices, and Option C incorrectly tries to unpack `kwargs.keys()`.", + "code_context": "main(apple=1.99, banana=0.99, orange=1.49)\n# should return 4.47" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments. For ex", + "score": 3, + "evidence_item_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "This snippet contains the exact prompt of the question, providing the student with the context of summing keyword argument values, although it lacks the specific code implementation for the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Identical question prompt; identifies the task as summing flexible keyword argument values." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Explains that flexible keyword arguments are handled as key-value pairs, which helps a student understand that the input is a dictionary-like object." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary iteration ('for letter in string') and access ('counts[letter]'), providing a conceptual bridge to how dictionaries are handled in loops." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Matches the exam question context perfectly." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Connects 'keyword arguments' to 'key-value pairs'." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the exact question text is present in the snippets, the critical technical detail (choosing between .values(), .items(), and .keys()) is not explicitly explained. A student with zero knowledge would know *what* they are trying to do but not *which method* provides the numeric values vs. the string keys.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the 'what' (summing keyword arguments) but lack the 'how' (dictionary methods for iteration).", + "missing_concepts": [ + "Difference between .keys(), .values(), and .items() in dictionary iteration", + "Syntax for unpacking items in a loop (e.g., 'for k, v in kwargs.items()')", + "The fact that **kwargs acts as a dictionary inside the function" + ], + "proposed_fix": "Add a dedicated 'Dictionary Iteration' snippet that explicitly labels what each method returns (keys, values, or both)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Dictionary & **kwargs Iteration. Content: 'def main(**kwargs): \\n # kwargs.keys() -> names (strings)\\n # kwargs.values() -> values (numbers/data)\\n # kwargs.items() -> both (name, value)\\n for val in kwargs.values(): total += val'", + "why_helpful": "This directly addresses the trap in the exam question by explaining the return types of dictionary methods.", + "why_maybe_unnecessary": "If the student already understands basic dictionary concepts from a general programming background, they might guess correctly, but for a zero-knowledge student, this is essential.", + "recommended_direction": "add_this" + }, + { + "kind": "edit_existing", + "target_item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "proposal": "Expand search_text to include the solution logic: 'To sum prices passed as keywords, iterate over kwargs.values() to get the numbers, not the keys.'", + "why_helpful": "Turns a placeholder into a functional solution reference for that specific recurring exam question.", + "why_maybe_unnecessary": "", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:09:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {word: len for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to the length of that word. The other options either reverse key/value order or use invalid logic.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text, including the list 'words' and the goal to create 'word_lengths', effectively serving as a direct answer key." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Directly matches the question and likely provides the correct code segment in its full text." + }, + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Features a similar 'Which of the following code segments will work' format for dictionary creation, helping the student recognize patterns in dictionary logic." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows a scenario where keys (names) are mapped to values (ages), reinforcing the concept of transforming lists into dictionary pairs." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "As an identical question, this is sufficient to solve the problem by recognition." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the identical question from a previous exam (Resit 22/23).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While a direct match exists, there is no conceptual explanation of the dictionary comprehension syntax ({key: value for item in iterable}).", + "missing_concepts": [ + "Dictionary Comprehension Syntax", + "Dictionary Unpacking Rules" + ], + "proposed_fix": "Add a conceptual key point or AI-generated section specifically defining the syntax and common pitfalls (like key/value order) of dictionary comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Key Point' explaining Dictionary Comprehensions: '{k: v for k in list}' where 'k' is the key and 'v' is the value. Emphasize that the key comes before the colon.", + "why_helpful": "It gives the student the 'rule' instead of just a specific answer, allowing them to solve variations of the question.", + "why_maybe_unnecessary": "The direct match in the exam snippets might be enough for a student looking for a quick fix.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:09:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades.\n\nThe students list contains strings representing the names of students.\nThe grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears. B builds lists of students per grade instead of counting them.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text, the expected output, and explicitly states that 'Option a' is the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Exact match for the question and identifies the correct code segment." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the same pattern: creating a dictionary from a list where the keys are the list items. It also confirms that a similar 'Option A' logic is valid for this pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides context for creating a dictionary from two parallel lists (names and ages), which mirrors the students and grades structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Since this is the identical question with the answer provided, it is sufficient on its own." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the exact question from the exam bank along with the solution.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps exist because the exact question is present in the source materials.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:09:51Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the right result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This snippet is an exact match for the question, containing the same 'math_scores' dictionary, the same scenario, and mentions the code segments 'a' and 'b'." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Identical question and data structure; directly answers the problem." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates calculating an average from a dictionary, which is the core logic required for the math scores problem." + }, + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Shows a structurally identical dictionary (employee_ratings) and the goal of finding/printing specific names based on values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Contains the specific problem text and data, making it the most direct reference for a student with no prior knowledge." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes a snippet that is an exact replica of the question. Even without Python knowledge, the student can match the 'math_scores' variable and the problem description to the snippet.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While an exact match exists, the snippet text in 'exam-extra_practice-4' mentions an indentation error in Option A, whereas the target question's answer is 'c' (both work). This could cause confusion.", + "missing_concepts": [ + "sum() and len() functions on dictionary values", + "Explicit confirmation that both iterating via .keys() and iterating directly over a dictionary yield the same keys." + ], + "proposed_fix": "Add a conceptual snippet explaining that sum(d.values()) / len(d) is the standard way to find a dictionary average, and that 'for k in d' is equivalent to 'for k in d.keys()'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Analytics' snippet: 'To calculate average: avg = sum(my_dict.values()) / len(my_dict). To find items above average: for key in my_dict: if my_dict[key] > avg: print(key). Note: for key in my_dict is the same as for key in my_dict.keys().'", + "why_helpful": "It explains the underlying logic of the two options (A and B) in the question, clarifying why they are functionally identical despite different syntax.", + "why_maybe_unnecessary": "The student might just rely on matching the exact question if they find snippet 4.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:10:10Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the logic of list comprehensions as a filter ('keeps numbers that satisfy conditions'), which is the core structure of the code segment." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Clarifies how the 'if' condition inside a list comprehension acts as a filter for elements." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Demonstrates string iteration using 'for letter in string', helping a beginner understand how the comprehension traverses 'x'." + }, + { + "item_id": "kp-2", + "rationale": "Explains that methods are functions attached to objects (like .islower() to char) and that they return values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the comprehension filtering logic." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Shows string iteration." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The structural logic (comprehension and iteration) is covered by existing snippets, but the specific behavior of '.islower()'—particularly that it returns False for spaces and punctuation—is not documented in any candidate snippet.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The student can understand 'how' the loop runs but not 'what' the specific filter (.islower) does with non-alphabetic characters like ' ', '!', and ','.", + "missing_concepts": [ + "islower() method definition", + "islower() behavior on non-alphabetic characters (spaces/symbols)" + ], + "proposed_fix": "Add a Key Point detailing common string boolean methods (islower, isupper, isdigit) and their results on various character types." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: String Case Testing. .islower() returns True ONLY if the character is a lowercase letter. It returns False for uppercase letters, spaces, and punctuation (e.g., 'a'.islower() is True, but 'A', ' ', and '!' are False).", + "why_helpful": "Directly explains why spaces and punctuation are excluded from the result list in the question.", + "why_maybe_unnecessary": "A student might guess 'islower' refers only to lowercase letters, but 'zero knowledge' implies they might not know if a comma has a case.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:10:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "Explains the `append` method, which is the only list-modifying operation in the question's code. However, it does not explain the loop structure or the math operators." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Clarifies how `.append()` works with lists, which is central to building the result list." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains that `print` is a built-in function used to output arguments to the screen, helping a novice understand the final line." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a `for x in lst` loop and `.append()`, providing some pattern matching for how elements move from one list to another." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "Covers list mutation (append)." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Covers output (print)." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows basic loop iteration and list accumulation." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "Crucial concepts are missing: the `zip()` function, which pairs elements from two lists, and the floor division operator `//`. Without knowing `zip()`, a student won't know that 'a' comes from list1 and 'b' from list2. Without knowing `//`, they cannot perform the calculation required to distinguish between options (b) and (d).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets do not define the 'zip' function or the 'floor division' operator, both of which are required to solve the logic and the arithmetic of the question.", + "missing_concepts": [ + "zip() function for parallel iteration", + "floor division operator (//)", + "unpacking multiple variables in a for loop (for a, b in ...)" + ], + "proposed_fix": "Add a manual or AI-generated snippet specifically covering common Python operators (//, %, **) and the built-in zip() function." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Python Arithmetic Operators. Content: + (addition), - (subtraction), * (multiplication), / (division), // (floor division: divides and rounds down to nearest integer), % (modulo: remainder), ** (exponentiation). Example: 5 // 2 results in 2.", + "why_helpful": "Directly explains the // operator used in the code context to reach the correct answer.", + "why_maybe_unnecessary": "Basic math might be assumed, but floor division is specific to programming languages.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Parallel Iteration with zip(). Content: The zip() function takes multiple iterables (like lists) and aggregates them into tuples. Example: for a, b in zip([1, 2], [3, 4]): prints (1, 3) then (2, 4).", + "why_helpful": "Explains how the 'for a, b in zip(list1, list2)' loop processes both lists simultaneously.", + "why_maybe_unnecessary": "None; it is critical for this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:10:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "This snippet is the exact same question and provides the logic for why negative steps like [::-2] and [-1::-2] produce the desired list." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Identical question and explanation of negative slicing logic." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Shows another example of list manipulation to achieve a reversed sequence [5, 4, 3, 2, 1]." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Explains the mechanics of slicing with a step (range(0, 7, 3)) and partition slicing (x[0:3])." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Directly answers the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One of the snippets is the exact exam question being asked, including the start of an explanation that validates the correct slicing logic for multiple options.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact answer is present, a student without the specific 'extra practice' snippet would struggle to understand nested slicing (like option A or C) because the concepts of 'slice of a slice' aren't explicitly taught in a general way in the other snippets.", + "missing_concepts": [ + "Nested slicing (applying a second slice to the result of a first slice)", + "Formal definition of [start:stop:step] syntax" + ], + "proposed_fix": "Add a foundational snippet or subtopic detail explaining that 'numbers[a:b:c][x:y:z]' applies the second slice to the intermediate list produced by the first." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Nested Slicing Logic. Content: Slicing creates a new list. You can apply another slice immediately after: my_list[start:stop:step][new_start:new_stop:new_step]. The second slice acts on the results of the first.", + "why_helpful": "This helps the student evaluate options A and C which use two sets of brackets.", + "why_maybe_unnecessary": "The student might just find the exact matching question snippet and stop there.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:11:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", leaving only the second occurrence replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "While the topic is loops, this snippet explicitly demonstrates string slicing syntax (`alphabet[1::2]`), which is the fundamental mechanism used in Option A of the question to surgically replace text." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides the only direct syntax example of string slicing (accessing parts of a string using brackets)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Involves extracting specific substrings from complex strings (URLs), mirroring the logic needed to find specific indices in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Deals with strings where characters (dashes) need to be handled/formatted, which conceptually relates to the .replace() logic in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Slicing syntax reference." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "String parsing logic reference." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The candidate snippets are almost entirely irrelevant to the specific 'replace' count argument and the specific 'find' start-index argument. While the question provides a hint for .find(), no snippet explains that .replace(old, new, count) limits replacements to the first N occurrences, which is critical to understanding why Option B works. Slicing is shown but not explained in a way that helps a zero-knowledge student understand `sentence[index + 4:]`.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of documentation or examples for string methods with optional arguments (like count in replace or start in find) and no clear explanation of 'surgical' string reconstruction using concatenation and slicing.", + "missing_concepts": [ + "str.replace(old, new, count) - the 'maxreplace' parameter", + "str.find(sub, start) - the 'start' index parameter beyond what is in the question hint", + "Using slicing for index-based string reconstruction (sentence[:i] + 'new' + sentence[i+n:])" + ], + "proposed_fix": "Add a snippet or topic card specifically covering 'String Manipulation and Surgical Replacement' that demonstrates find(), index-based slicing, and the count parameter in replace()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card titled 'Targeted String Modification' showing: 1. .replace('text', 'new', 1) only replaces the first match; 2. .find('text', 5) starts searching after index 5; 3. sentence[:5] + 'new' + sentence[10:] replaces characters between index 5 and 10.", + "why_helpful": "This directly maps to the mechanics of both Option A and Option B, allowing a student to verify the multi-step replacement logic in Option B and the slicing offsets in Option A.", + "why_maybe_unnecessary": "The question contains a hint for find(), but it is insufficient for a zero-knowledge student to confidently evaluate the replace() logic or the math behind index+4 slicing.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:11:34Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the requested sentence exactly, including the word \"and\" before the final fruit. Option A joins the list as \"apple, banana, orange\" and does not produce the exact requested wording.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves formatting a string with variables from a list of items (Name and Grade), which is the closest conceptual match to the f-string formatting required by the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Contextual match for printing formatted strings using data from lists." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows list/string indexing syntax (e.g., [1::2]), which is necessary to understand Option B's use of fruits[0], fruits[1], etc." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions string methods like .map() and splitting, providing some context for string manipulation methods like .join()." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Provides the 'string with placeholders' pattern." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides the indexing syntax." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides string manipulation context." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Shows a list of dictionaries, helping a student understand how lists store multiple items." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "No snippet explicitly demonstrates f-string syntax (f\"...\") or the .join() method. A student with zero knowledge would not know that .join(fruits) omits the word 'and', nor would they confirm that the f-string syntax in Option B is valid for inserting list elements.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gaps are f-string interpolation syntax and the behavior of the string .join() method compared to manual indexing.", + "missing_concepts": [ + "f-string syntax and variable interpolation", + "String .join() method behavior", + "List indexing syntax (list[n])" + ], + "proposed_fix": "Add a snippet or reading material item that explicitly compares f-strings using indexing vs f-strings using .join() for list elements." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: f'Items: {items[0]}, {items[1]}' and comparing it to ', '.join(items).", + "why_helpful": "This directly addresses the core logic of the question: distinguishing between a simple join and specific formatting requirements like 'and' before the last item.", + "why_maybe_unnecessary": "If the student has access to a 'String Fundamentals' cheat sheet section not included in these exam snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:11:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})", + "b": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "c": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "d": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)" + }, + "correct": "d", + "explanation": "Option D constructs one aligned series for the local parts and one for the domains, then returns them in a DataFrame with the correct column names. The other options either overwrite values, build the wrong structure, or use the wrong field names.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Directly addresses the 'flexible number of arguments' concept (*args) required by the function signature in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains the syntax and behavior of functions accepting a flexible number of arguments (*args)." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Contextualizes the concept of 'extracting' parts of a string (like a TLD or an email local part) from a formatted input." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Introduces Pandas Series, which are used in the correct answer (Option D) to build the final DataFrame." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers the *args requirement." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Covers the string parsing/extraction logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Covers the Pandas Series component." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Helps a student understand how to map keys to values (like column names to data lists) which is central to building the DataFrame." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover *args, the concept of string extraction, and the existence of Pandas Series. However, the exact syntax for splitting a string at a character (split('@')) and the constructor for a DataFrame from a dictionary of Series are not explicitly shown in the code samples, requiring the student to infer these patterns.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing explicit examples of the .split() method and the pd.DataFrame() constructor using a dictionary input.", + "missing_concepts": [ + "String splitting syntax (string.split('@'))", + "Pandas DataFrame construction from a dictionary of Series or lists", + "List comprehension for transforming a tuple of arguments" + ], + "proposed_fix": "Add a snippet demonstrating how to use split() to divide a string into components and another showing the creation of a multi-column DataFrame from a dictionary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: data = {'col1': [1, 2], 'col2': [3, 4]}; df = pd.DataFrame(data). Include a brief note on using .split() to break strings into list components.", + "why_helpful": "This directly bridges the gap between having extracted components and returning them as a structured DataFrame, which is the core task of the exam question.", + "why_maybe_unnecessary": "Option D uses pd.Series explicitly, so a student might guess the DataFrame structure if they understand Series, but the dictionary-to-DataFrame mapping is a common stumbling block.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:12:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "False\nTrue", + "c": "False\nFalse", + "d": "True\nFalse" + }, + "correct": "a", + "explanation": "The object is created with name 'John Smith', and because no gender argument is passed, the default value 'not specified' is used. Both comparisons therefore evaluate to True.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Directly demonstrates how default arguments work (num2=10, num3=20) when a function is called with fewer values than parameters, which is the exact logic needed to determine the 'gender' value in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explains the default parameter behavior which is critical for understanding why 'gender' defaults to 'not specified'." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the conceptual pattern for defining classes with attributes (name, mode) initialized during construction." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Shows equality comparison (==) logic, helping the student evaluate whether the print statements will result in True or False." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Covers the 'default value' logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Covers the 'class attribute initialization' pattern." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "By combining the OOP class structure from one snippet and the default argument mechanics from another, a student can clearly see that missing arguments trigger default values and that self.name is assigned from the first argument.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the concepts are covered across multiple snippets, there isn't a single example that explicitly shows the 'obj.attribute' access syntax alongside default arguments in a class context.", + "missing_concepts": [ + "explicit instance attribute access syntax (object.attribute)" + ], + "proposed_fix": "Add a snippet demonstrating a class with a default argument and a subsequent print of that attribute (e.g., p = Person('A'); print(p.age))." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: 'class User: def __init__(self, id, status=\"active\"): self.id = id; self.status = status; u = User(123); print(u.status == \"active\")'", + "why_helpful": "This merges OOP structure with default argument logic and attribute access in one clear example, mirroring the question's complexity.", + "why_maybe_unnecessary": "The student can technically deduce the answer by combining the 'Arguments' and 'OOP Fundamentals' snippets currently available.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:12:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original expression computes the number of days between January 10 and January 1, then adds 1, which yields 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-day-of-year", + "rationale": "It uses the exact logic from the question—subtracting January 1st from a date, accessing .days, and adding 1—to compute a day-of-year value, making the pattern directly recognizable." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Provides the structural template for the date arithmetic and explains the '+ 1' logic for inclusive day counting." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explicitly explains the mechanics: subtracting datetimes creates a timedelta, and .days returns the difference as an integer." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Shows the required imports and the syntax for creating datetime objects and performing subtraction." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Essential for the formula pattern." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Essential for understanding the data types involved (timedelta and integer attributes)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the day-of-year formula logic and the explanation of .days allows a student to calculate that the original code equals 10 and identify Option D as the equivalent result.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is clear, the 'strptime' function used in the question is not explicitly demonstrated in the code snippets, though it is inferable from the string content.", + "missing_concepts": [ + "Explicit demonstration of datetime.strptime() syntax and format codes like %Y/%m/%d" + ], + "proposed_fix": "Add a snippet demonstrating how to convert strings to datetime objects using strptime with common format codes." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'dt = datetime.strptime(\"2023/01/10\", \"%Y/%m/%d\")' with a comment explaining that %Y is year, %m is month, and %d is day.", + "why_helpful": "It removes any ambiguity for a non-Python user about how the string '2023/1/10' is being processed.", + "why_maybe_unnecessary": "Most students will correctly guess that '2023/1/10' represents January 10, 2023, without needing the technical definition of strptime.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:13:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df[['Player', 'Age']])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df.loc[:, 'Age'])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing in this form does not accept the tuple (1, 'Age') to select a single cell.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet is the most relevant as it explicitly discusses creating a new DataFrame by selecting specific columns for specific rows, which touches upon the mechanics of row/column indexing in Pandas." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Covers selecting specific columns and rows, helping the student understand valid selection patterns (relevant to options A and B)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a printed Pandas DataFrame with indices and columns, helping a zero-knowledge student visualize the 'df' described in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows basic column access like df['A'], which validates the use of string keys in brackets for column selection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using boolean masks and column lists for selection." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Contextualizes what a DataFrame looks like." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Confirms basic bracket notation for columns." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain the specific syntax rules of .loc vs. standard brackets, nor do they explicitly show that a tuple like [1, 'Age'] is invalid in standard brackets. A student with zero Python knowledge would not be able to confidently identify why Option D causes an error while Option A (nested brackets) does not.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The existing snippets do not define the difference between label-based indexing (.loc) and position-based or standard bracket indexing. Crucially, the 'standard bracket error' for multi-axis indexing is never mentioned.", + "missing_concepts": [ + "Pandas .loc syntax for simultaneous row and column selection", + "The invalidity of df[row, col] vs the validity of df.loc[row, col]", + "Double bracket syntax df[['col1', 'col2']] for selecting multiple columns" + ], + "proposed_fix": "Add a summary or rule-based snippet that contrasts valid selection methods (df['col'], df[['col1', 'col2']], df.loc[row, col]) with common syntax errors like df[row, col]." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas Selection Cheat Sheet. Content: To select one column: df['A']. To select multiple: df[['A', 'B']]. To select specific rows and columns by label: df.loc[row_index, 'column_name']. Note: Using df[index, 'column'] directly results in an error.", + "why_helpful": "It directly addresses the core logic required to distinguish between valid Pandas syntax and the error-inducing Option D in the exam question.", + "why_maybe_unnecessary": "If the goal is only to use existing exam questions as context, but since the current questions are truncated, they don't provide the syntax rules clearly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:13:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "animals methods", + "question": "You have the following definition for a class called Animals:\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs = True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin = True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "def walk():\n return sound if legs else 'Cannot walk!'\ndef swim():\n return sound if fin else 'Cannot swim!'", + "d": "def walk():\n if legs == True:\n return sound\n else:\n return 'Cannot walk!'\ndef swim():\n if fin == True:\n return sound\n else:\n return 'Cannot swim!'" + }, + "correct": "a", + "explanation": "Option A is the only choice that defines both instance methods with self and correctly returns self.sound when the corresponding boolean attribute is truthy, otherwise the required fallback string.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses adding a method (compare) to a class that involves logical conditions and attribute access, mirroring the structure required for walk() and swim()." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to structure a class method that performs logic based on instance attributes." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining a class and using the 'self' parameter in the constructor, which helps the student recognize that 'self' is a standard part of class definitions." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "While about functions, it demonstrates conditional logic, which is necessary to understand the 'if/else' requirements of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates instance method definition logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows class attribute initialization and the 'self' pattern." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Helps distinguish between proper comparison (==) and assignment (=) which is critical for identifying why option B is wrong." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets correctly point to the need for 'self' in methods and the use of 'self.attribute' for access. However, none of the snippets explicitly demonstrate the Python ternary operator (val if cond else other) used in the correct answer (Option A), nor do they explicitly warn against the common '=' vs '==' error in Option B for a student with zero Python knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing explicit examples of the ternary conditional operator and the distinction between instance methods vs. static/plain functions inside a class context.", + "missing_concepts": [ + "ternary conditional operator", + "comparison operator (==) vs assignment (=) in if-statements", + "explicit 'self' requirement for instance methods vs functions" + ], + "proposed_fix": "Add a snippet or AI-generated section that contrasts a plain function with a class method, specifically showing both 'if/else' and ternary syntax for returning values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Instance Methods and Conditional Returns' that shows: 1. A method using self. 2. A return statement using the 'X if condition else Y' syntax. 3. A warning that '=' cannot be used for comparison in 'if' statements.", + "why_helpful": "This would directly address the syntax found in the correct answer (ternary) and the syntax error in the most tempting distractor (Option B).", + "why_maybe_unnecessary": "If the student is very observant, they might infer 'self' from the constructor snippets, but the ternary operator is likely to be confusing.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:13:52Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "movie review methods", + "question": "You have the following definition for a class named Movie.\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute,\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and return the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segments will work as intended." + }, + "correct": "d", + "explanation": "Option A is broken because add_review uses list-plus-number syntax and compare immediately returns on the first loop iteration, so it never returns other.title when the other movie has the higher rating. Option B is also broken because add_review and rating are missing self and compare compares method objects instead of calling them.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "Directly demonstrates the correct implementation of a class with an add_review method using .append() and an average calculation method, which allows a student to identify the syntax errors in both options A and B." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Shows the correct way to append to a list attribute and structure methods with 'self', highlighting the flaws in both code segments." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Discusses the logic for a 'compare' method based on average review scores, providing the conceptual framework for the question's objective." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Reinforces the requirement for 'self' in method definitions and how attributes are initialized, which is a key error in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Covers appending to lists, method definitions with self, and average calculation logic." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippet 'manual-oop-state-compare' provides a nearly identical class structure (Book vs Movie). A student can see that adding to a list requires .append() (ruling out A's +=) and that methods must include 'self' (ruling out B).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective for this specific question because the AI-generated example perfectly mirrors the required methods.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:14:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "datetime weekly dates list", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "b": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "c": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "d": "This code segment will work as intended." + }, + "correct": "c", + "explanation": "After the first append, the newly added element is a formatted string, so on the next loop iteration the code tries to add a timedelta to a string instead of to a datetime object.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Mentions filtering 'non-integers', which introduces the concept that operations (like addition) are restricted to specific data types, mirroring the 'string vs datetime' conflict in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduces the principle of type-checking and the fact that functions/operations fail when applied to the wrong type (non-integers)." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Discusses a function that takes a string and returns a 10-digit string, helpful for understanding string-to-string transformations." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates iterating through a list of strings and performing operations based on their properties (lengths)." + } + ], + "minimal_sufficient_snippets": [], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "No snippets cover the 'datetime' or 'timedelta' modules. Without knowing that 'strftime' converts a datetime object into a string, a student cannot deduce that the second iteration of the loop fails because it tries to add a timedelta to a string.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete gap regarding the 'datetime' module's specific methods and the resulting object types.", + "missing_concepts": [ + "The return type of datetime.strptime (datetime object) vs datetime.strftime (string)", + "The requirement that timedelta can only be added to datetime objects", + "How list elements can change types across iterations in a loop" + ], + "proposed_fix": "Add a core library snippet for Week 4/Datetime explaining the conversion cycle: String -> strptime -> Datetime -> strftime -> String." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Datetime and Timedelta Operations'. Key points: 1. datetime.strptime() returns a datetime object. 2. datetime.strftime() returns a string. 3. Adding a timedelta to a datetime object works; adding it to a string causes a TypeError.", + "why_helpful": "It explicitly provides the technical knowledge needed to evaluate Option C, which is the correct answer and the core 'trick' of the question.", + "why_maybe_unnecessary": "If this is a rare topic, but since it appears in final exams, it is high-value.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:14:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "pandas date column from day month year", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A correctly constructs datetime objects in year-month-day order from the three columns and then formats them into the requested DD-MM-YYYY strings.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the essential Pandas syntax for creating a new column ('C') by performing operations on existing columns ('A' and 'B')." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows how to assign a new column to a DataFrame based on existing column values, which is the high-level goal of the question." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a clear example of using zip() to iterate over multiple lists simultaneously, explaining the syntax used in the question's list comprehension." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces the concept of transforming Series values (using .map or similar), which provides context for the row-wise logic required here." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers the Pandas column creation boilerplate." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Explains the zip() function for parallel iteration." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the snippets explain the 'Pandas' and 'zip' parts of the code, they completely lack information on the 'datetime' module. A student cannot know that 'datetime(year, month, day)' is the correct argument order (distinguishing A from C) or that 'strftime' is used for formatting rather than 'strptime' (distinguishing A from B/D).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets cover general structural patterns but miss the specific library knowledge (datetime) required to differentiate the answers.", + "missing_concepts": [ + "datetime.datetime constructor argument order (Year, Month, Day)", + "Usage of strftime() for date-to-string formatting", + "Difference between strftime (format) and strptime (parse)" + ], + "proposed_fix": "Add a snippet demonstrating the creation of a datetime object from integers and its subsequent formatting into a string." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: 'Datetime Construction and Formatting'. Content: 'from datetime import datetime; # Order: Year, Month, Day; dt = datetime(2023, 5, 1); # Format to string; s = dt.strftime(\"%d-%m-%Y\") # Returns \"01-05-2023\"'.", + "why_helpful": "This provides the exact 'missing piece' regarding argument order and method selection (strftime) needed to solve the exam question.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:15:12Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "pandas above average salary", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 1000\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "None of the blocks of code will work as intended.", + "c": "Both blocks of code will work as intended.", + "d": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])" + }, + "correct": "a", + "explanation": "Option A correctly computes the mean salary, builds both required columns, and prints the full DataFrame filtered to rows where Above_average is True. Option D does not print the result in the required way because it filters only on Salary_difference > 0 rather than explicitly using the Above_average column requested in the specification.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This snippet introduces the core logic of calculating the difference between elements in a Series and their mean, which is central to both Operations 1 and 2." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Explains the concept of processing elements relative to the mean of a sequence (Series)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates vectorized column operations (df['C'] = df['A'] + df['B']), which validates the syntax used in Operation 2." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Covers boolean masks and selecting rows from a DataFrame based on indices/conditions, relevant for Operation 3." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Logic for mean and difference calculations." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Syntax for creating new columns via vectorized math." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Syntax for filtering DataFrames with boolean masks." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Shows the .map() method, helping the student distinguish why Option D (which uses .map()) might be syntactically valid but strategically different from Option A." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "Existing snippets cover column math and filtering logic, but none explicitly show the `.mean()` method or the specific `df[df['col'] == True]` print syntax. A student with zero knowledge would have to infer that `.mean()` is the standard way to get an average in Pandas.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide a strong foundation for column creation and filtering, but the specific Pandas aggregation method '.mean()' and the explicit syntax for boolean filtering in a print statement are missing.", + "missing_concepts": [ + "df['col'].mean() method", + "df[df['bool_col'] == True] filtering syntax" + ], + "proposed_fix": "Add a snippet demonstrating basic Pandas descriptive statistics (mean, sum) and how to use a boolean column to filter a DataFrame." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Pandas Aggregation and Filtering. 'To calculate the average of a column, use df[col].mean(). To filter a DataFrame to show only rows where a condition is met, use df[df[col] > value] or df[df[bool_col] == True].'", + "why_helpful": "It directly connects the 'average' requirement in the question to the '.mean()' method and explains the filtering syntax needed for Operation 3.", + "why_maybe_unnecessary": "The 'extra_practice' snippet mentions 'above average' logic for dictionaries, but Pandas-specific syntax is distinct enough to warrant its own entry.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:15:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "pandas lambda output", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "b": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "c": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15", + "d": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18" + }, + "correct": "d", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing C values 16, 17, and 18.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "It explicitly mentions that the .map() method allows applying a function to a Series, which is the fundamental mechanism being used in the code (df['A'].map(...))." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that .map() applies a function to each element of a Series." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the syntax for creating a new column 'C' by performing operations on other columns ('A' and 'B')." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes a scenario of creating a new Series where each element is based on a calculation involving the original element and an aggregate (the mean), similar to the lambda sum logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides the 'apply function' logic for .map()." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides the DataFrame column assignment syntax." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides context for element-wise operations involving aggregates." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets explain .map() and column creation, there is zero information on 'lambda' syntax or the '.sum()' aggregation method. A student wouldn't know that 'lambda x: ...' defines a function or that 'sum()' produces a single value (15) to be added to each 'x'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The main gaps are the definition and syntax of lambda functions and the behavior of pandas aggregation methods like .sum().", + "missing_concepts": [ + "lambda function syntax (lambda x: ...)", + "pandas .sum() aggregation behavior", + "The concept of using an aggregate value inside a row-wise map/apply function" + ], + "proposed_fix": "Add a key point or exam snippet that explains anonymous (lambda) functions and common pandas aggregations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Lambda Functions in Pandas. 'lambda x: expression' creates a small anonymous function where 'x' represents the value of each row/element when used with .map() or .apply(). Example: s.map(lambda x: x + 10).", + "why_helpful": "This is critical for understanding what the 'lambda' keyword does in the question code.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Pandas Aggregations. Methods like .sum(), .mean(), and .count() return a single number representing the total/average/count of the entire Series/column. Example: df['B'].sum() equals the sum of all values in column B.", + "why_helpful": "The student needs to know that df['B'].sum() is a constant value (15) in this context, not another Series.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:15:54Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round1/resit-solutions-for-introduction-to-python-35761538.json b/data/vision_exam_pipeline/work_packets/evaluations/round1/resit-solutions-for-introduction-to-python-35761538.json new file mode 100644 index 0000000..3eac336 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round1/resit-solutions-for-introduction-to-python-35761538.json @@ -0,0 +1,2125 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q01", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q01", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_1", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "The three code lines evaluate to 2 * 3 == 6, 3 + 5 == 8, and 7 - 5 == 2, so each one is True. Therefore the correct choice is that all lines print True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ], + "evidence_topics": [ + "Lists and Sets" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This snippet contains the exact question, the specific list definition, and the step-by-step mathematical evaluation (e.g., 2 * 3 == 6) for each option, making it perfectly answerable without prior knowledge." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Identical to the exam question and provides the full numerical breakdown for options A, B, and C." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Provides the same question and evaluation logic, reinforcing the correct answer 'd'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "On its own, this snippet provides both the context and the solution logic required to verify the correct answer." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question being asked along with a detailed explanation of why each sub-expression evaluates to True.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover this specific question perfectly. However, if the question values were changed, the student would need a general rule for 2D indexing (row/column or list/tuple) and negative indexing.", + "missing_concepts": [ + "Negative indexing (e.g., x[-1] is the last element)", + "Nested indexing (e.g., x[0][1] accesses the second element of the first tuple)" + ], + "proposed_fix": "Add a foundational snippet explaining how x[i][j] works with both positive and negative integers for lists of tuples." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q02", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q02", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_1", + "question": "Executing the following program will produce an error. Why?\n\ndef power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)", + "options": { + "a": "Result is a local name that cannot be referenced outside of the function power.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "The function called power should not return the string 'The result of {} ** {} is: {}.'.format(num, factor, result), but the value of result." + }, + "correct": "a", + "explanation": "`result` is defined inside the function, so it has local scope. The line `print(result)` is outside the function and therefore cannot access that local variable.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-2-w3-scope" + ], + "evidence_topics": [ + "Scope" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-2-w3-scope" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "This snippet is an exact match for the exam question, identifying the specific function (power), the variable (result), and explaining that local scope prevents access from the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "Directly answers the specific question provided with identical variable and function names." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the conceptual definitions of local and global names, explaining that local names are only known inside the function." + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "Explains that a function leaves no traces and local names are gone after the function ends, reinforcing why the variable is inaccessible." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "Direct answer to the specific question." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Conceptual foundation for understanding scope." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact same question and a detailed explanation of the correct answer, as well as the underlying lecture theory.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent because the dataset includes the exact exam question being asked.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q03", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q03", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_3", + "question": "What will be printed by the following code segment?\n\ndef main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[None]", + "d": "[]" + }, + "correct": "b", + "explanation": "The function appends only elements whose type matches the type of `x`, which is `list`. Among the provided elements, only `[]` is itself a list, so the printed result is `[[]]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "What will be printed by the following code segment?", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-3-w3-return-behavior" + ], + "evidence_topics": [ + "Return Behavior" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-3-w3-return-behavior" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "This snippet describes the exact logic of the question: checking if the type of an element matches the type of the input list and identifying that only '[]' satisfies this condition, resulting in '[[]]'." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Directly explains the type-matching logic and the specific behavior for the empty list within a list." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Essentially a duplicate of the best snippet, providing identical reasoning and the correct final answer for this specific code pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Reinforces the concept of type checking (e.g., distinguishing between int, float, and str) which helps a student understand the 'type(i) == type(x)' mechanic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "This single snippet provides the complete logic, the evaluation of the specific input elements, and the final output." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains two snippets that are near-exact matches for the logic and result of the question provided, explicitly explaining why '[[]]' is the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets perfectly cover the problem. No gaps identified for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:41Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q04", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q04", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_3", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\ndef main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10']", + "b": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10', '1 * 11 = 11']", + "c": "This code produces an error as there is a missing argument when calling main.", + "d": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')" + }, + "correct": "a", + "explanation": "When `main(1)` is called, `y` uses its default value `11`. The loop runs for `i` values 1 through 10, so it returns a list of ten multiplication strings from `1 * 1 = 1` through `1 * 10 = 10`.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "Suppose you have the following function, which takes two integers as arguments: What will be printed by the following line of code: print(main(1))", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "This snippet is a near-identical match to the target question, explicitly explaining that y defaults to 11 and describing the while loop's boundary condition." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Provides the exact logic and explanation for the specific code provided in the question." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Matches the question perfectly and explicitly notes the loop range (1 to 10) and the use of f-string formatting." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Reinforces the concept of default arguments with multiple examples, helping the student understand the general pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Contains the exact logic and answer required." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Two snippets in the candidate list are effectively the same question as the target, providing direct explanations for the default argument and loop behavior.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets provide direct answers to this specific question. No significant gaps exist for this particular problem.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:16:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q05", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q05", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "Functions Built-in", + "question": "Suppose you have a list called x, where:\n\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Both snippets produce [5, 4, 3, 2, 1]. The first removes duplicates and sorts the unique values in reverse order, and the second slices every second element from the reversed list.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "Suppose you have a list called x. Which of the following code segments will print the following list? [5, 4, 3, 2, 1]", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ], + "evidence_topics": [ + "Functions and Imports" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "This snippet is a direct match for the exam question. It explicitly explains that Option A uses set(x) to remove duplicates and sorted(..., reverse=True) to order them, and it begins to explain Option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Direct match that explains the removal of duplicates via sets and the reverse sorting logic." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Another direct match for the question, reinforcing the set and slicing explanation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides general context for list slicing syntax (e.g., [1::2]), which helps a student understand the mechanics of the slicing used in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Provides the direct answer and logic for both Option A and Option B of the specific question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact explanation for the question provided, identifying Option C as the correct answer and explaining the functions involved.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the snippets are direct matches, the text is truncated in the search results. A student with zero knowledge might struggle to fully verify the slicing logic ([::-2]) because the explanation is cut off mid-sentence.", + "missing_concepts": [ + "Complete step-by-step trace of the slice [::-2] on the provided list x." + ], + "proposed_fix": "Update the snippet text to ensure the explanation for the slicing operation is complete and easy to follow." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "proposal": "Ensure the text includes: 'Option B uses slicing [::-2], which starts from the end of the list and takes every second element, resulting in [5, 4, 3, 2, 1].'", + "why_helpful": "It allows a zero-knowledge student to manually verify the slicing result rather than just taking the snippet's word for it.", + "why_maybe_unnecessary": "The student may already be convinced by the explanation of Option A and the knowledge that 'Both' is an option.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:17:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q06", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q06", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "Function Flexible Argument", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "B sums the keyword argument values, which is exactly what the function should do. A incorrectly adds the keyword names, and C iterates over keys in a way that does not match the intended structure.", + "code_context": "def main(**kwargs):\n # Sum the values passed as keyword arguments" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments. For ex", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "This snippet contains the exact problem statement and example (main(apple=1.99...) returns 4.47) used in the question, providing direct context." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Exact match for the question prompt and example case." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Confirms that 'flexible number of keyword arguments' relates to dictionary-like key-value pairs, which helps bridge the concept to dictionary methods." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Shows another example of a function accepting a 'flexible number of arguments' to return a sum, reinforcing the pattern of using loops for totals." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Provides the problem context." + }, + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Explains the structure of keyword arguments as key-value pairs." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets provide the exact question text and identify that keyword arguments function as dictionaries, they do not explicitly explain the difference between .values(), .keys(), and .items() methods. A student with zero Python knowledge might struggle to choose between options B and C without knowing that .values() is required to access the numbers (prices).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets identify the problem but lack a technical definition of how to iterate over dictionary values vs keys.", + "missing_concepts": [ + "Difference between dict.values(), dict.keys(), and dict.items()", + "Implicit conversion of **kwargs into a dictionary inside the function" + ], + "proposed_fix": "Add a summary snippet or code example explaining that **kwargs creates a dictionary, and summing values requires iterating over .values()." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-6-w3-arguments", + "proposal": "Append the correct code solution and a brief explanation: 'Use **kwargs to capture keyword arguments as a dictionary; use kwargs.values() to iterate over and sum only the values (prices).'", + "why_helpful": "It directly answers the 'how' for a student who recognizes the problem but doesn't know the specific dictionary method names.", + "why_maybe_unnecessary": "The student might infer it if they have a general 'Dictionary Methods' snippet elsewhere, but specialized **kwargs help is better.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:17:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q07", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q07", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries Comprehension", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {len: word for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to its length. The other options either reverse the key/value order or use invalid comprehension logic.", + "code_context": "words = ['example', 'python', 'exam']" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 7, + "question_summary": "Assume you already have a list of strings called words. You need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are the", + "score": 3, + "evidence_item_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ], + "evidence_topics": [ + "Dictionaries and Mappings" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet is a verbatim match for the exam question, featuring the exact variable names (words, word_lengths) and the specific task of mapping strings to their lengths." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Directly identifies the specific problem context and provides the identical prompt." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Describes the general logic for creating a dictionary where keys are list elements and values are character counts (lengths), identifying it as a 'standard dictionary comprehension'." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows a similar task (creating person_dict from names/ages) which helps reinforce the key:value construction pattern in dictionaries." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides the exact context and problem statement." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Provides the conceptual explanation of the correct mechanism (dictionary comprehension for lengths)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of a verbatim question match (Snippet 1) and a conceptual match for the 'element-to-length' mapping logic (Snippet 16) allows a student to identify the correct code pattern even without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the snippets cover the problem, the search text in the candidate snippets is truncated, which might hide the actual code for the correct option 'c'.", + "missing_concepts": [ + "explicit syntax demonstration of {k: len(k) for k in list}" + ], + "proposed_fix": "Enrich the dictionary comprehension snippets to explicitly show the {key: value for item in iterable} syntax in the search_text preview." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "proposal": "Update the search_text to include the full solution code for option C: word_lengths = {word: len(word) for word in words}.", + "why_helpful": "The current snippet cuts off at 'Option A is a vali', which might lead a student to think A is the answer, even though the provided question says C is correct.", + "why_maybe_unnecessary": "Snippet 16 provides the conceptual backing, but clarity is always better.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:18:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q08", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q08", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades:\n- The students list contains strings representing the names of students.\n- The grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears, which matches the requested dictionary. B stores lists of students per grade, so it does not produce counts.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet is a near-identical match to the question being asked, providing the exact context, example data, and even confirming 'Option a' as the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Identical question and answer match." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows a similar pattern of creating a dictionary from a list and validates a specific code segment as correct, helping the student understand dictionary construction." + }, + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the logic of adding keys to a dictionary and incrementing values (e.g., adding shirts), which is the core logic of the correct answer." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Provides the direct answer to the specific question." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Introduces the concept of using two parallel lists (names and ages) to build a dictionary, which helps differentiate why the 'zip' approach in option b might be used but is incorrect for counting." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question and its solution. Even without prior knowledge, a student can simply match the 'grade_counts' requirement to the snippet providing 'Option a'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is directly provided in one snippet, the underlying logic of the 'initialize if missing, then increment' pattern is not explicitly explained as a general concept in the snippets.", + "missing_concepts": [ + "The 'if key not in dictionary' pattern for counting", + "Difference between assignment (=) and incrementing (+=) in a dictionary context" + ], + "proposed_fix": "Add a conceptual snippet or a lecture-based 'Key Point' that explains the standard algorithm for counting occurrences using a dictionary." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Key Point' snippet titled 'Counting with Dictionaries' that explains: To count items, check if the item is a key. If not, set it to 0. Then, increment by 1.", + "why_helpful": "This would allow a student to solve the problem by understanding the logic rather than just finding the identical question in the database.", + "why_maybe_unnecessary": "The direct match snippet already ensures the student can answer the specific exam question correctly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:18:27Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q09", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q09", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the correct result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text, the same dictionary (math_scores), and the same objective (finding scores above average)." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Identical question and data structure; directly maps to the exam problem." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates calculating an average from a dictionary of numerical values (monthly_sales)." + }, + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Shows how to iterate through a dictionary (employee_ratings) to find specific values based on a condition." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Contains the specific logic and variable names used in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippet 'exam-extra_practice-4-w2-dictionaries-and-mappings' is an exact match for the exam question, providing the student with the direct context needed to identify the correct code segments.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide an exact match for the question logic. The only potential gap is the truncated explanation in the snippet which mentions an indentation error in Option A, whereas the question claims both work.", + "missing_concepts": [], + "proposed_fix": "None required for answerability, but cleaning up the snippet text to ensure the explanation matches the 'Correct: C' logic would reduce confusion." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "proposal": "Ensure the 'search_text' includes the full code for options a and b and clarifies why both work, matching the provided question explanation.", + "why_helpful": "The current snippet cut-off mentions an indentation error for Option A, which contradicts the 'Correct: C' (both work) answer in the exam question. Aligning these prevents student confusion.", + "why_maybe_unnecessary": "The student can likely infer the logic from the code patterns even if the explanation is cut off.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:18:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q10", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q10", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how a list comprehension with an 'if' clause works as a filter, which is the core structural logic of the question's code segment." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Explains the filtering logic of list comprehensions ([x for x in list if condition])." + }, + { + "item_id": "kp-2", + "rationale": "Clarifies that methods (like .islower()) are functions attached to objects (like strings) and explains their general behavior." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "Provides the blueprint for interpreting the list comprehension syntax and the filtering process." + }, + { + "item_id": "kp-2", + "rationale": "Helps the student identify '.islower()' as a method being called on the character objects." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain the list comprehension's filtering logic, but none of them define the '.islower()' method or its behavior regarding punctuation and whitespace. A student might guess 'islower' means 'lowercase letter', but they wouldn't be certain how it handles commas or spaces without a specific definition.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student can understand the 'how' (filtering via comprehension) but not the 'what' (the specific criteria of islower).", + "missing_concepts": [ + "Definition of the .islower() string method", + "Behavior of .islower() on non-alphabetic characters (spaces, punctuation)" + ], + "proposed_fix": "Add a key point or reference snippet covering 'Boolean String Methods' (islower, isupper, isdigit, isalpha) and their return values for non-letters." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: Boolean String Methods. Methods like .islower(), .isupper(), and .isdigit() return True only if the string contains at least one character and all characters meet the criteria. Importantly, .islower() returns False for spaces, punctuation, and numbers as they are not lowercase letters.", + "why_helpful": "It provides the missing definition needed to definitively choose option (a) over (b) or (c) by clarifying that symbols and spaces are excluded.", + "why_maybe_unnecessary": "A student might intuitively guess that 'islower' only applies to letters, but 'zero prior knowledge' requires explicit confirmation.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:19:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q11", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q11", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "It demonstrates the use of the `.append()` method, which is the mechanism used to build the result list in the question code." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows list initialization and the `.append()` method." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains the `print()` function, which is necessary to understand how the final result is displayed." + }, + { + "item_id": "aiq-2", + "rationale": "Reinforces the concept of list mutation through methods like `.append()`." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Explains .append()" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains print()" + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While 'append' and 'print' are covered, the two most critical concepts required to solve this specific problem—the `zip()` function (pairing elements from two lists) and the `//` operator (floor division)—are completely absent from the candidate snippets. A student with zero Python knowledge would not know what 'zip' does or that '//' rounds down to the nearest integer.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to explain the iterative pairing logic of zip and the mathematical behavior of floor division.", + "missing_concepts": [ + "zip() function behavior", + "// (floor division) operator", + "unpacking multiple variables in a for loop (for a, b in ...)" + ], + "proposed_fix": "Add a snippet or common question entry that specifically explains how `zip` works with two lists and clarifies the difference between `/` and `//`." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a common question snippet: 'How do zip() and floor division (//) work?'. Content: `zip(list1, list2)` pairs elements by index: (list1[0], list2[0]), (list1[1], list2[1]). `//` is floor division, which divides and rounds down to the whole number (e.g., 5 // 2 = 2).", + "why_helpful": "Directly addresses the two primary 'black boxes' in the question for a non-Python user.", + "why_maybe_unnecessary": "Basic math might be assumed, but zip is definitely a specific Python syntax that needs explanation.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:19:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q12", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q12", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "This snippet is a near-exact match for the question, containing the same list, target value, and explanations for how specific slicing parameters (start -1, step -2) produce the requested result." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Directly addresses the list slicing logic for the specific numbers and step values used in the question." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Explains the [::-1] slicing syntax as a method to reverse a list, which is critical for evaluating options A, B, and C." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Provides a clear example of the [start:stop:step] notation (specifically step) within the 'Sequences and Access' topic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "Provides the core logic for the specific problem." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Clarifies the reversal syntax." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-extra_practice-6-w1-sequences-and-access' contains the exact logic for slicing with negative steps and starting points on this specific list, making the answer derivable even without prior knowledge if the student matches the logic.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is present, there is a lack of explicit documentation on 'nested slicing' (applying a second slice to the result of a first slice), which is required for options A and C.", + "missing_concepts": [ + "nested slicing execution order", + "implicit start/stop indices when step is negative" + ], + "proposed_fix": "Add a dedicated subtopic or tip explaining that in 'list[a:b:c][d:e:f]', the first slice is computed entirely before the second slice is applied to that resulting subset." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-extra_practice-6-w1-sequences-and-access", + "proposal": "Expand the search text/explanation to explicitly define why option A ([::-2][::-1]) results in [2, 4, 6, 8, 10] (it reverses the reversed slice).", + "why_helpful": "The current snippet text is truncated and might confuse students if the option letters (a, b, c, d) are shuffled in the exam.", + "why_maybe_unnecessary": "The logic 'starts at -1, step -2' is already present and might be enough for a smart student to eliminate options.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:19:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q13", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q13", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "string - find - 3", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", so only the second occurrence remains replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates string slicing syntax (`alphabet[1::2]`), which is the foundational concept needed to understand the code in Option A." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of using square bracket notation to slice a string variable, helping a user interpret the syntax used in Option A." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Describes a problem involving string formatting and removing separators (dashes) from a string, which conceptually relates to the string replacement task." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Involves extracting specific substrings from a URL, a task that typically requires finding indices and slicing, mirroring the logic in Option A." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Example of string slicing syntax." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Context for string manipulation/formatting." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Context for substring extraction." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the question provides a helpful hint for the find() method, no snippet explains the count parameter in string.replace() (required for Option B) or basic [start:end] slicing and string concatenation (required for Option A).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus heavily on dictionaries and OOP, leaving a significant gap in foundational string manipulation methods and slicing syntax.", + "missing_concepts": [ + "The optional 'count' argument in string.replace(old, new, count)", + "Basic string slicing syntax [start:end]", + "String concatenation using the '+' operator" + ], + "proposed_fix": "Add a technical reference snippet or a lecture example that explicitly covers the 'replace' method with counts and demonstrates how to rebuild a string using slices and '+', as this is a common exam pattern." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Common String Operations' showing: 1. text.replace('a', 'b', 1) to replace only the first occurrence; 2. index-based slicing like text[:5] and text[10:]; 3. concatenating slices with +.", + "why_helpful": "This would allow a student to verify both Option A (slicing) and Option B (replace with count) without prior knowledge.", + "why_maybe_unnecessary": "The question hints at find(), but find() alone isn't enough to understand the replacement logic in the options.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:20:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q14", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q14", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "string - fstring - 3", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the required sentence exactly, including the word \"and\" before the final fruit. Option A joins the list without \"and\", so it does not produce the exact requested output.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves printing a specific string template with variable placeholders ('[NAME] has received a grade of [GRADE]'), which is the closest conceptual match to the string formatting required for f-strings." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Illustrates the requirement of matching a specific output string format using variables." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows the use of square brackets `[]` for sequence access (slicing), which hints at the indexing syntax used in Option B." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides context for string manipulation in Python, though it focuses on different methods (.map, .split)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Closest match for string template logic." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Introduces sequence bracket syntax." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The candidate snippets completely lack the foundational concepts needed: f-string syntax (f'{}'), basic list indexing (list[i]), and the behavior of the .join() method. A student without prior knowledge would be unable to distinguish why Option B is correct and Option A is not (specifically regarding the inclusion of 'and').", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a total absence of basic string formatting and list indexing documentation in the current selection.", + "missing_concepts": [ + "f-string syntax and variable interpolation", + "List element access via integer indexing (0, 1, 2)", + "The exact behavior of '.join()' (specifically that it does not handle the Oxford comma/last element differently)" + ], + "proposed_fix": "Add fundamental snippets covering f-strings from Week 1 or Week 4, and list indexing examples from Week 1." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining f-strings: f'Hello {name}' replaces {name} with the variable value.", + "why_helpful": "Essential to understand how both Option A and Option B work.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining list indexing: fruits[0] is the first item, fruits[1] is the second.", + "why_helpful": "Necessary to decode what Option B is actually doing.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining ', '.join(list): Result is 'item1, item2, item3' with no 'and'.", + "why_helpful": "Allows the student to realize Option A is a distractor that produces a different string than requested.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:20:49Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q15", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q15", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "string - operations - 3", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)", + "b": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "c": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "d": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})" + }, + "correct": "a", + "explanation": "Option A builds aligned pandas Series for the local parts and domains, then returns them in a DataFrame with the correct column names. The other options either swap fields, overwrite values, or construct the DataFrame incorrectly.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains how to use the .split() method to extract specific parts of a string based on a separator (like ';' or '@'), which is the core logic needed to extract 'local' and 'domain' parts from email addresses." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly addresses string splitting and part extraction in a pandas/data context." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains the syntax for a function that accepts a flexible number of arguments (*args), which is required for the main() function signature." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides context on Pandas Series, which are used in the correct answer (Option A) to construct the columns of the DataFrame." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides the string splitting logic." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Provides the *args flexible argument syntax." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides the Pandas Series context used in the solution." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain *args and string splitting, which are the hardest parts. However, a student with zero knowledge might still struggle to understand how to combine list comprehensions with dictionary keys and pd.DataFrame construction into the exact format of Option A.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is a lack of an example showing the construction of a DataFrame from a dictionary of lists or Series, especially when those lists are created via list comprehensions.", + "missing_concepts": [ + "DataFrame construction from a dictionary of Series", + "List comprehension syntax for processing function arguments (*args)" + ], + "proposed_fix": "Add a snippet that demonstrates creating a DataFrame from a dictionary where the values are lists generated by splitting strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'df = pd.DataFrame({\"part1\": [x.split(\"-\")[0] for x in args], \"part2\": [x.split(\"-\")[1] for x in args]})'", + "why_helpful": "This pattern perfectly matches the logic required in the question (Option A), showing how to map processed strings into DataFrame columns.", + "why_maybe_unnecessary": "Students might be able to piece this together if they understand Dictionaries and Series separately, but a combined example is much clearer for beginners.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:21:21Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q16", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q16", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Easy_1", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "True\nFalse", + "c": "False\nTrue", + "d": "False\nFalse" + }, + "correct": "a", + "explanation": "The name comparison is true because the object stores 'John Smith', and the gender comparison is also true because the default value 'not specified' is used when no gender is provided.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly demonstrates how default arguments work when a function is called with fewer arguments than parameters (e.g., add_numbers(5, 15)), which is the core logic required to understand why 'gender' becomes 'not specified'." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explains default parameter behavior, allowing the student to deduce the value of the 'gender' attribute." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Shows the syntax for defining a class with 'name' and 'mode' attributes initialized in the constructor, which mirrors the Employee class structure." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Demonstrates the use of the equality operator (==) and the resulting boolean output (True/False) when printed." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Handles the default argument logic for the missing 'gender' value." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Handles the OOP syntax and attribute assignment (self.name = name)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the OOP structure snippet and the default arguments snippet provides all the mechanical rules needed to trace the code execution accurately.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover class structure and default arguments separately. While sufficient, a single example combining both would reduce the cognitive load for a novice.", + "missing_concepts": [ + "Explicit link between __init__ parameters and attribute access (self.attribute)." + ], + "proposed_fix": "Add a snippet or edit an existing OOP one to include a default parameter in the __init__ method." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "proposal": "Update the search_text to show a snippet of the code for the Vehicle class, specifically including a default value for the 'mode' attribute (e.g., mode='land').", + "why_helpful": "It would show the exact pattern used in the question (OOP + Default Arg) in a single visual context.", + "why_maybe_unnecessary": "The logic can currently be synthesized by looking at two different snippets.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:21:43Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q17", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q17", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_2", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original code computes the difference in days between January 10 and January 1, then adds 1, yielding 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-day-of-year", + "rationale": "This snippet provides the exact logic used in the question: subtracting January 1st from a date and adding 1 to calculate the day count. It explicitly explains that adding 1 makes Jan 1st 'day 1'." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Shows the '(date - start_date).days + 1' pattern and explains the logic for day numbering." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explains the technical mechanism: subtracting datetimes creates a timedelta, and .days retrieves the integer difference." + }, + { + "item_id": "ks-86cd7ede1c", + "rationale": "Provides the general rule for datetime arithmetic and mentions that subtracting datetimes creates timedeltas." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-day-of-year", + "rationale": "Matches the mathematical logic of the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Explains the data types and attributes (.days) involved." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the 'manual-datetime-day-of-year' example and the 'exam-intro' explanation covers both the logic (+1 offset) and the syntax (.days attribute). A student can intuitively map '2023/1/10' to Jan 10th even without knowing strptime details.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets explain the arithmetic and the result type well, but there is no explicit explanation of strptime format codes like %Y, %m, or %d.", + "missing_concepts": [ + "datetime.strptime format codes" + ], + "proposed_fix": "Add a snippet explaining common datetime format codes (%Y, %m, %d, %H, %M, %S) to ensure students can accurately parse strings into dates." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String to Datetime Parsing (strptime)\nContent: datetime.strptime(string, format) converts text to a date object. \nFormat codes: %Y (4-digit year), %m (month 01-12), %d (day 01-31), %H (hour), %M (minute).\nExample: datetime.strptime('2023/1/10', '%Y/%m/%d') creates a date for Jan 10, 2023.", + "why_helpful": "It removes the small inferential leap required to understand that strptime is creating a date for January 10th based on the provided format string.", + "why_maybe_unnecessary": "Most students will guess the meaning of '%Y/%m/%d' correctly given the sample string '2023/1/10'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:22:06Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q18", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q18", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "pandas - easy - 3", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df.loc[:, 'Age'])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df[['Player', 'Age']])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing does not accept the tuple (1, 'Age') in this form.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This is the only snippet that explicitly mentions 'Inspecting and Selecting Data' and discusses selecting columns using a list (e.g., ['B']), which relates to the logic in options B and C." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Discusses row/column selection logic, providing context for how DataFrames are filtered." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Identifies the core topic of the question (Inspecting and Selecting Data) and shows a sample DataFrame structure." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows basic column access (df['A'], df['B']) which helps a student understand the standard bracket syntax used in Option C." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides the closest conceptual match for DataFrame selection patterns." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates standard column selection which validates part of the question's logic." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets demonstrate the use of '.loc' (Options A and B) or explain that standard brackets 'df[row, col]' are invalid for DataFrames. While Item 12 mentions selection, the actual code syntax is not visible in the snippet text, making it impossible for a zero-knowledge student to distinguish between valid and invalid indexing methods.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a clear contrast between basic indexing (df['col']) and label-based indexing (df.loc[row, col]).", + "missing_concepts": [ + "pandas .loc syntax", + "difference between df[] and df.loc[]", + "KeyError/TypeError for multi-axis indexing in standard brackets" + ], + "proposed_fix": "Add a summary card or snippet that explicitly states: 'Use df.loc[row, col] for simultaneous row/column selection; standard brackets df[...] only accept column names, lists of columns, or slices.'" + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Pandas Indexing Rules' snippet showing: 1. df['ColName'] (Valid), 2. df[['C1', 'C2']] (Valid), 3. df.loc[index, 'Col'] (Valid), 4. df[index, 'Col'] (Error).", + "why_helpful": "It directly maps to the four options in the question, allowing a student to identify the error through pattern matching.", + "why_maybe_unnecessary": "If a student already knows dictionary-like indexing, they might guess D is wrong, but .loc (A/B) would still be confusing.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:22:35Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q19", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q19", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Function_1", + "question": "You have the following definition for a class called Animals:\n\nclass Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ...\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs == True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin == True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "c", + "explanation": "Both shown method implementations use the instance attributes to return the animal's sound when the relevant boolean attribute is present and the required fallback message otherwise.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly describes writing a method that uses instance attributes to return a result based on logic (comparing scores), which is the core task of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows logic inside a class method using instance data." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Provides the basic template for defining a class with attributes, which helps a novice understand the structure of the provided code context." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Demonstrates simple if/else branching logic, which is necessary for evaluating option (b)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates the concept of a method accessing its own attributes to perform a check." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Shows how attributes are initialized and mapped to 'self', explaining the existence of self.legs/self.fin." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Explains standard conditional logic (if/else)." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain class structure, attributes, and basic 'if/else' logic. However, they do not explain the 'ternary operator' syntax used in option (a) (x if condition else y) nor the fact that 'if self.legs' is equivalent to 'if self.legs == True' for boolean values, which is critical for choosing 'c' over just 'b'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing explanations for Python-specific conditional expressions (ternary operators) and truthy/falsy evaluation of booleans.", + "missing_concepts": [ + "Ternary operator syntax (return x if condition else y)", + "Boolean evaluation (if x vs if x == True)", + "Explicit 'self' attribute access syntax explanation" + ], + "proposed_fix": "Add a snippet from the 'Conditions' or 'OOP' week that explicitly shows both standard if/else and the conditional expression version of the same logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Conditional Expressions vs Statements' showing: 'return \"Yes\" if check else \"No\"' is equivalent to 'if check: return \"Yes\" else: return \"No\"'.", + "why_helpful": "Directly enables a student to recognize that both option (a) and (b) in the question are functionally identical.", + "why_maybe_unnecessary": "A student might guess if they understand standard 'if' blocks, but they won't be certain.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining 'self' as a reference to the current instance, used to access attributes defined in __init__.", + "why_helpful": "Ensures the student understands that 'self.legs' refers to the value passed during 'cat = Animals(..., legs=True)'.", + "why_maybe_unnecessary": "The existing 'Vehicle' class snippet hints at this, but doesn't explain the lookup mechanism within a method.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:22:57Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q20", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q20", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Hard_3", + "question": "You have the following definition for a class named Movie.\n\nclass Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ...\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute.\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and returns the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "d", + "explanation": "The first code segment is broken because it tries to add an integer directly to a list and its compare logic cannot return the other movie's title correctly. The second code segment omits self where needed and compares method objects instead of method results.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This snippet provides a near-identical class structure (Book vs Movie) and demonstrates the correct implementation of add_review (using .append) and average/rating. It directly exposes the syntax errors in Option A (using += on a list) and Option B (missing self)." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Demonstrates proper method definition with self, attribute access, and list appending, which are the main points of failure in the options." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "While textual, it describes a 'compare' method logic for objects, helping the student understand the conceptual goal of the method." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Reinforces the pattern of initializing multiple attributes using self in the constructor." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Covers 2 out of 3 methods and demonstrates self-parameters and list mutation." + } + ], + "answerability": { + "status": "partial", + "confidence": "high", + "rationale": "The student can identify why Option A is wrong (list += int error vs .append) and why Option B is wrong (missing self in method signatures) by looking at 'manual-oop-state-compare'. However, the subtle error in Option B (comparing methods instead of calling them with brackets) is not explicitly contrasted in any snippet.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No snippet explicitly demonstrates the difference between a method reference and a method call (e.g., self.rating vs self.rating()), nor does any snippet show one instance calling a method on another instance (other.rating()).", + "missing_concepts": [ + "method calls vs method references (brackets usage)", + "inter-object method calls (other.method())" + ], + "proposed_fix": "Add a comparison method to the Book example in 'manual-oop-state-compare' that uses 'other.average()' to demonstrate proper calling syntax." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "manual-oop-state-compare", + "proposal": "Add a compare method: def is_better(self, other): return self.average() > other.average()", + "why_helpful": "This would show the necessity of using brackets () when calling a method on both self and another object, directly addressing the 'd' answer rationale.", + "why_maybe_unnecessary": "The existing snippet already helps eliminate A and B based on the self parameter and list mutation syntax.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:23:17Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q21", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q21", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_1", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "b": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "c": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "d": "This code segment will work as intended." + }, + "correct": "b", + "explanation": "After the first append inside the loop, the list contains formatted date strings. On the next iteration the code tries to add a timedelta to that string, which is not allowed.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduces the concept of type-checking and filtering (integers vs strings/floats), which helps establish that operations in Python are sensitive to whether data is a string or a numeric object." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Highlights the distinction between strings and numeric types during calculations, which is conceptually similar to the datetime/string conflict." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Provides an example of a function iterating through a list and processing elements, which helps a student understand the basic execution flow of the question's code." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Shows a list containing dictionaries (complex objects), which reinforces the idea that lists can store different types of data simultaneously." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Necessary to hint at type-dependent failures." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The question requires specific knowledge of the 'datetime' module: 1) That strptime returns a datetime object, 2) That strftime returns a string, and 3) That timedelta cannot be added to a string. None of the provided snippets mention datetime, strftime, or the specific rules of timedelta arithmetic. A student with zero knowledge would not realize that the list elements change from objects to strings after the first iteration.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets focus on general logic and basic data types, but the question hinges on the specific behavior of the datetime library and the 'gotcha' of mixing formatted strings with datetime arithmetic.", + "missing_concepts": [ + "The 'datetime' module and 'timedelta' usage", + "The difference between a datetime object (computable) and its string representation (non-computable)", + "The specific return types of .strftime() and .strptime()" + ], + "proposed_fix": "Add a snippet or card explaining that formatting functions like strftime() produce strings, which prevents further mathematical operations (like adding a timedelta) that require actual datetime objects." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card for 'Datetime and Timedelta Arithmetic'. Explicitly state: 'datetime.strptime()' returns an object you can do math with. 'obj.strftime()' returns a STRING for display. You CANNOT add a timedelta to a string. Example: (date_obj + timedelta) works, but (date_string + timedelta) fails.", + "why_helpful": "This directly explains the 'b' distractor in the question, which is the correct answer.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:23:50Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q22", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q22", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_3", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas module is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A builds real datetime objects using year, month, and day in the correct order and then formats each one as DD-MM-YYYY.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which is the first step of the required operation." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows how to create a new column in a DataFrame by performing operations on existing columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Illustrates string manipulation within a pandas Series, which helps the student understand that column values can be transformed into new string formats." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Though focused on dictionaries, it introduces the concept of processing multiple lists/columns together (names and ages), similar to the zip requirement in the datetime question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Confirms the df['NewColumn'] = ... syntax used in all options." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Provides context for element-wise string transformation in pandas." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Relates to the concept of iterating through multiple parallel data sources (zip)." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the 'datetime' module, the 'datetime()' constructor (specifically the order of year, month, day), or the 'strftime' method for string formatting. A student with zero knowledge would have no way to distinguish between Option A (correct order) and Option C (incorrect order).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets cover basic Pandas column creation but entirely miss the core 'Datetime' and 'String Formatting' requirements of this 'Hard' level question.", + "missing_concepts": [ + "datetime.datetime constructor argument order (year, month, day)", + "datetime.strftime() method and format codes (e.g., %d, %m, %Y)", + "zip() function for parallel iteration over multiple columns", + "list comprehensions for creating Series" + ], + "proposed_fix": "Add a snippet from a lecture or manual entry that explicitly shows creating a datetime object and formatting it with strftime." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Datetime Formatting' that shows: from datetime import datetime; dt = datetime(2023, 5, 1); print(dt.strftime('%d-%m-%Y'))", + "why_helpful": "This provides the missing link for the student to understand the constructor order and the formatting codes required to pick Option A over C or B.", + "why_maybe_unnecessary": "Only if the student is expected to already know the datetime library, but the prompt specifies 'zero prior knowledge'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:24:11Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q23", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q23", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "pandas - hard - 3", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 100\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])", + "c": "Both blocks of code will work as intended.", + "d": "None of the blocks of code will work as intended." + }, + "correct": "c", + "explanation": "Both code blocks compute the rounded mean salary, derive an above-average indicator, compute salary differences from that mean, and filter the rows with positive differences.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This snippet directly addresses the logic of calculating the mean of a Series and performing arithmetic operations (difference) on each element, which is central to Operations 1 and 2." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Covers the 'mean' calculation and Series-wide arithmetic (subtraction), which is key for finding the salary difference." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the fundamental syntax for creating a new column in a DataFrame based on operations between other columns." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces the `.map()` method, which is used in Option B to apply conditional logic or transformations to each row." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Explains mean and element-wise differences." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows column creation syntax (df['C'] = ...)." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Shows usage of .map() for applying functions." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a 'boolean mask' to select specific rows, which helps with Operation 3's filtering logic." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover mean calculation, column creation, and the map method. However, they do not explicitly show the 'lambda x: ...' syntax with an if-else inside, nor do they clearly demonstrate the 'df[df['col'] == value]' filtering syntax in a way that a student with zero Python knowledge could confidently reconstruct.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing clear examples of boolean indexing for filtering DataFrames and the specific use of ternary operators within lambdas/maps.", + "missing_concepts": [ + "Boolean indexing (df[condition])", + "Lambda functions with conditional logic (if-else)", + "List comprehension for creating Series" + ], + "proposed_fix": "Add a snippet demonstrating how to filter a DataFrame using a boolean condition and another showing a map/lambda with an if-else statement." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Pandas Boolean Filtering' showing: df_filtered = df[df['Salary'] > 50000].", + "why_helpful": "This directly enables the student to understand the syntax for Operation 3.", + "why_maybe_unnecessary": "Snippet exam-intro_python_sample_final_24_25-6 mentions boolean masks, but the code snippet in the preview is cut off.", + "recommended_direction": "add_this" + }, + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "proposal": "Ensure the example code includes a lambda with a condition, e.g., s.map(lambda x: 'High' if x > 10 else 'Low').", + "why_helpful": "It validates the syntax used in Option B of the question.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:24:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:resit-solutions-for-introduction-to-python-35761538-q24", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q24", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "pandas - lambda - 3", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18", + "b": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "c": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "d": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15" + }, + "correct": "a", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing 16, 17, and 18 in column C.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explicitly mentions that the .map() method allows applying a function to each element in a Series, which is the core mechanic of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains the purpose of .map() for applying functions to Series values." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides the structural context of creating a new column 'C' from existing columns 'A' and 'B' in a DataFrame." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Shows operations involving a Series and an aggregate value (like mean, similar to sum) for each element." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Introduces .map()." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Introduces column derivation (A, B -> C)." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Contextualizes calculations involving the whole Series and its properties." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain .map() and the context of creating a new column, but they do not explicitly define the 'lambda' syntax or the '.sum()' method for a student with zero prior knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "While the general pandas context and .map() functionality are touched upon, the specific syntax of anonymous 'lambda' functions and the behavior of '.sum()' on a column are missing.", + "missing_concepts": [ + "lambda functions (anonymous functions)", + "Series.sum() method for aggregation" + ], + "proposed_fix": "Add a snippet or key point that demonstrates a lambda function adding a scalar value (like a sum) to each element of a column." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a key point (e.g., kp-pandas-lambda-agg) that shows: 'df['C'] = df['A'].map(lambda x: x + constant)' and explains that 'lambda x' represents each value in column 'A'.", + "why_helpful": "This bridge is necessary to understand how the lambda variable 'x' interacts with the result of 'df['B'].sum()'.", + "why_maybe_unnecessary": "If the student already understands functions and basic aggregation, the existing .map() snippet might be enough to guess.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:25:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round1/sample-final-plus-answers.json b/data/vision_exam_pipeline/work_packets/evaluations/round1/sample-final-plus-answers.json new file mode 100644 index 0000000..78f8a16 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round1/sample-final-plus-answers.json @@ -0,0 +1,2724 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "exam_id": "sample-final-plus-answers", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round1:sample-final-plus-answers-q01", + "question_id": "sample-final-plus-answers-q01", + "exam_id": "sample-final-plus-answers", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "vehicle class defaults", + "question": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation.\nThe name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string \"land\".\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A correctly defines the constructor with `self`, stores both attributes on the instance, and gives `vehicle_mode` the default value `\"land\"`.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any st", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 1, + "question_summary": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any st", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-init-default", + "rationale": "Directly explains the concept of optional constructor arguments with default values and provides a code pattern nearly identical to the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Explains the specific syntax for default values in __init__ which is the core of the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Reinforces the problem context by providing the exact question text from a past exam." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides redundant but helpful context for the specific OOP scenario described." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Contains both the conceptual explanation and the syntax needed to identify Option A as the correct implementation." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippet 'manual-init-default' explicitly covers the mechanics of default values in class constructors and even uses the same variable names (vehicle_mode='land'), making it easy for a student to match with the correct option.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets cover the primary challenge (default values). However, a beginner might still struggle to understand why 'self' is required or why attributes must be assigned to 'self' rather than just used as local variables.", + "missing_concepts": [ + "Explicit role of 'self' in instance attribute assignment vs local variables" + ], + "proposed_fix": "Add a snippet explaining that 'self.attribute = value' is necessary to persist data on the object, which would help distinguish Option A from Option D." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Instance Attributes and 'self'. Content: 'To make an attribute available on an object (like my_car.name), you must assign it to self inside the __init__ method (e.g., self.name = vehicle_name). Without self, the variable only exists temporarily during creation.'", + "why_helpful": "Provides a clear reason to choose Option A over Option D, as Option D defines variables without self.", + "why_maybe_unnecessary": "Option A is already the most likely choice for a student matching the default value syntax provided in 'manual-init-default'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:25:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q02", + "question_id": "sample-final-plus-answers-q02", + "exam_id": "sample-final-plus-answers", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "book rating output", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The stored review scores are 5, 3, and 3. Their average is 11 / 3 = 3.666..., and the method rounds that to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_r", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 2, + "question_summary": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_r", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This snippet explicitly teaches how to trace the state of 'self' across multiple method calls using a nearly identical 'Book' class structure with an 'append' method and an average calculation." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Directly models the state-tracking logic (appending to a list in an object) required to solve the question." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Clarifies the behavior of the '.append()' method, which is crucial for understanding how the review scores are stored." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Provides a reference for the exact class structure, helping the student recognize the pattern of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Explains state tracking and the sum/len average pattern." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Validates how lists grow with append." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain the OOP mechanics (classes, self, append) very well. However, they do not explicitly define the 'round(value, 1)' function or the built-in 'sum()' and 'len()' functions, which are necessary for a student with zero Python knowledge to perform the final calculation accurately.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the OOP structure is covered, the mathematical built-ins used in the return statement are not explained.", + "missing_concepts": [ + "Built-in function: round(x, n) - rounding to n decimal places", + "Built-in function: sum() - totaling a list", + "Built-in function: len() - counting items in a list" + ], + "proposed_fix": "Add a snippet or AI example covering 'Common Built-in Math Functions for Collections' that explains sum, len, and round." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Common Math Built-ins for Lists. Content: Use `sum(list)` to add all numbers, `len(list)` to count items, and `round(number, 1)` to round to one decimal place. Example: `round(10/3, 1)` returns `3.3`.", + "why_helpful": "The question relies on a calculation involving all three of these functions. Without knowing what 'round(..., 1)' does, a student might guess 4 (b) or 3.67 (d).", + "why_maybe_unnecessary": "Students might infer sum/len from context, but 'round(..., 1)' is more specific.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:25:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q03", + "question_id": "sample-final-plus-answers-q03", + "exam_id": "sample-final-plus-answers", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "student grade formatting", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\nFor example, if\nstudents = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 75.\nBernard has received a grade of 80.\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']}. \")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {student['Grade']}. \")", + "c": "for student in students:\n print(f\"{student['Name']} has received a grade of \" + str(student[\"Grade\"]))", + "d": "for student, grade in students.items():\n print(f'{student} has received a grade of {grade}.')" + }, + "correct": "a", + "explanation": "Option A iterates through the list of dictionaries and prints each student's name together with that student's grade. The other options incorrectly call `.items()` on the list or use the wrong data access pattern.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 3, + "question_summary": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is a verbatim match for the exam question provided, containing the exact problem statement regarding list of dictionaries and grade formatting." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Identical problem statement including the specific requirements for grade formatting and dictionary keys." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "A duplicate of the question from a different exam source, reinforcing the likely pattern of the question." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a practical example of dictionary iteration logic and validating code segments, which helps a student understand why certain options are valid." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Directly answers the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the candidate list. A student can simply match the problem description to the snippet and find the corresponding correct code segment.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the question text is perfectly covered, the specific syntax for 'one decimal place' (f-string precision) is mentioned in the prompt but not explicitly demonstrated in the code snippets provided in the search text.", + "missing_concepts": [ + "f-string precision formatting (e.g., :.1f)", + "difference between list iteration and dictionary .items() iteration" + ], + "proposed_fix": "Add a dedicated 'cheat sheet' style snippet explaining list-of-dictionary iteration and f-string number formatting." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Printing List of Dictionaries with Formatting. Content: To iterate through a list of dicts: `for item in my_list: print(f\"{item['key']}\")`. To format decimals to 1 place: `{value:.1f}`.", + "why_helpful": "The exam question specifically mentions one decimal place, but Option A in the JSON actually omits the format specifier. Providing the specific syntax ensures the student can handle variations where precision is required.", + "why_maybe_unnecessary": "The 'source_exam' snippets likely already contain the full solution in the actual rendered card.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:26:13Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q04", + "question_id": "sample-final-plus-answers-q04", + "exam_id": "sample-final-plus-answers", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "phone number formatting", + "question": "You need to write a function called format_phone_number that formats phone numbers.\nThe output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) at various places.\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A calls `replace` but does not store its result, so it returns the original unchanged string. The other options all build and return the digits without the dashes.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# should all return \"0205251400\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 4, + "question_summary": "Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions", + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "This snippet contains the exact explanation for the question: it explicitly states that strings are immutable and that the `.replace()` method returns a new string without modifying the original, which is why Option A fails." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Directly explains the behavior of `.replace()` and string immutability, which is the key to identifying the incorrect code segment." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Provides the exact context and problem statement for this specific phone number formatting question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "The explanation within this snippet ('Strings in Python are immutable. The .replace() method returns a new string but does not modify the original') is sufficient to solve the problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include a direct explanation of the specific trap in the question (string immutability and return values of string methods).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps. The existing snippets cover both the question context and the underlying technical reason for the correct answer.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:26:28Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q05", + "question_id": "sample-final-plus-answers-q05", + "exam_id": "sample-final-plus-answers", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "pandas even-row selection", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.9\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that looks like this, when printed:\n\n B\n2 8.2\n4 3.6\n6 8.4\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters the even-numbered row labels and keeps column `B` as a one-column DataFrame, matching the printed target. The other options use invalid indexing, select the wrong column/positions, or return a Series instead of the shown DataFrame.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 5, + "question_summary": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet is a direct match for the question. It explicitly explains that using a boolean mask on the index (df.index % 2 == 0) and specifying the column as a list (['B']) is the correct way to filter even rows and return a one-column DataFrame." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides the specific logic for even-row indexing and DataFrame column selection needed for the answer." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Shows the exact DataFrame structure (rows 1-6) mentioned in the question, helping the student visually map the data to the code." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides general context for pandas DataFrame column operations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Contains the key explanation for the logic used in option A." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides the visual data context." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains the exact question text and an explanation that matches the target answer perfectly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are highly relevant, but the indexing logic (modulo operator on index) could be explained more generically for students to apply to other variations.", + "missing_concepts": [ + "The role of the modulo operator (%) in finding even/odd numbers", + "The distinction between .loc (label-based) and .iloc (position-based) selection" + ], + "proposed_fix": "Add a foundational snippet explaining how boolean masks work with df.index to select rows based on label properties." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "proposal": "Add the text of the DataFrame 'df' (rows 1-6) to this snippet so it is fully self-contained without needing to look at 'exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data'.", + "why_helpful": "It ensures the student has both the data context and the solution logic in a single view, which is critical for zero-knowledge students.", + "why_maybe_unnecessary": "The student can select multiple snippets, but a single consolidated card is more efficient for a cheat sheet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:26:52Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q06", + "question_id": "sample-final-plus-answers-q06", + "exam_id": "sample-final-plus-answers", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "pandas df2 derivation", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False).loc[:, [\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A would keep all five rows after sorting the index descending, so it would not produce the shown three-row df2. The other options can all produce rows 4, 3, and 2 with columns A, C, and D in the displayed order.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ], + "evidence_topics": [ + "String Operations and Methods" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 6, + "question_summary": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ], + "evidence_topics": [ + "String Operations and Methods" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This snippet is a verbatim match for the exam question, explicitly explaining that Option A is incorrect because it retains all 5 rows of df1 while df2 only has 3 rows." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Direct answer and rationale for the exact question asked." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides general logic for selecting specific rows and columns in a DataFrame, which helps understand options B, C, and D." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Shows a visually similar DataFrame structure (4 columns, multiple rows) and the pattern of derivation via selection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Provides the complete logic needed to solve the problem by identifying the mismatch in row counts." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-7-w4-string-fundamentals' contains the identical question and a clear explanation of the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gap exists because the exact question is present in the source exam bank.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:27:20Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q07", + "question_id": "sample-final-plus-answers-q07", + "exam_id": "sample-final-plus-answers", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "datetime month parser", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "`\"03/02/2013\"` is parsed with `%m/%d/%Y`, so its month is 3. `\"03.02.2013\"` matches neither separator rule and becomes `None`. `\"03-02-2013\"` is parsed with `%d-%m-%Y`, so its month is 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 7, + "question_summary": "Which of the following code lines could NOT have created df2 from df1?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 7, + "question_summary": "Which of the following code lines could NOT have created df2 from df1?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This snippet is a direct match for the exam question, containing the exact code, input values, and a step-by-step explanation of the return value logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Directly explains the month parsing logic for both date formats used in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Provides context for handling strings with '-' separators, which mirrors one of the branching conditions in the question." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Helps a novice understand basic 'for' loop iteration and 'if/else' membership checks ('in') used in the code." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Contains the exact solution and reasoning for the provided problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the verbatim question and explanation from a previous exam, making the answer explicitly available.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact match exists, the snippets lack a general-purpose reference for datetime formatting codes which would be necessary if the question parameters (like date formats) were slightly altered.", + "missing_concepts": [ + "General datetime format specifiers reference (%m, %d, %Y)", + "List comprehension syntax explanation" + ], + "proposed_fix": "Add a summary item detailing common strptime format characters to enable solving variations of this parsing logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Formatting Cheat Sheet' snippet listing %d (day), %m (month), %Y (year), and %H:%M (time).", + "why_helpful": "It empowers the student to decode any strptime format string rather than just recognizing this specific exam solution.", + "why_maybe_unnecessary": "The database already contains many specific exam questions covering these codes individually.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:27:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q08", + "question_id": "sample-final-plus-answers-q08", + "exam_id": "sample-final-plus-answers", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "dictionary comprehension lengths", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the only dictionary comprehension that maps each string to its own length. Option B makes a list, Option C makes a set, and Option D reverses the intended key-value direction.", + "code_context": "list_1 = [ ... ]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 8, + "question_summary": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 8, + "question_summary": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ], + "evidence_topics": [ + "String Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This snippet is a direct match for the question. It explicitly states the correct answer and explains the difference between dictionary, list, and set comprehensions, which is exactly what a student needs to distinguish between the provided options." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Directly identifies the identical question and explains the correct syntax (Option A) vs incorrect ones (Option B, C)." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Reinforces the pattern by presenting a nearly identical problem (mapping words to their lengths in a dictionary) and confirming the correct approach." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides another example of creating a dictionary from lists (names to ages), helping the student recognize the 'key: value' mapping pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Provides the exact solution and high-level explanation of the syntax differences." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippet 'exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions' is the exact same question and answer pair. It provides both the correct answer and a conceptual explanation of why other structures (lists, sets) are incorrect.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are exceptionally strong because they include the exact question being asked. No conceptual gaps exist for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:28:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q09", + "question_id": "sample-final-plus-answers-q09", + "exam_id": "sample-final-plus-answers", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Datetime parsing", + "question": "Take a look at the following code segment.\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "The first string contains `/`, so it is parsed as month/day/year and gives month 3. The second string contains neither `-` nor `/`, so it becomes `None`. The third contains `-`, so it is parsed as day-month-year and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 9, + "question_summary": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 9, + "question_summary": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime", + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This snippet is a direct match for the question provided. It explicitly explains the logic: strings with '/' use %m/%d/%Y (month 3), strings with '-' use %d-%m-%Y (month 2), and others return None." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Directly explains the specific datetime parsing logic and format codes used in the question." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Helps a student understand the 'for loop' and 'append' logic used to build the result list in the code context." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Illustrates how calling a function with different arguments leads to different return values, which is the core of tracing the get_months call." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Provides the exact logic and mapping needed to solve the specific problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains an identical question/explanation snippet that breaks down the exact strings and format codes used in the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While a direct answer exists, there is no general reference for datetime format codes (%d, %m, %Y) or the .month attribute, which would be necessary if the question were slightly modified.", + "missing_concepts": [ + "datetime.strptime format codes documentation", + "datetime object attributes (month, day, year)", + "list comprehension basics" + ], + "proposed_fix": "Add a summary card for the 'datetime' module covering common formatting directives and object properties." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Cheat Sheet' snippet: '%d: Day (01-31), %m: Month (01-12), %Y: Year (4-digit). datetime.strptime(str, format) parses strings; object.month extracts the month integer.'", + "why_helpful": "It would allow students to solve any datetime parsing question rather than relying on finding a verbatim copy of the exam question.", + "why_maybe_unnecessary": "The verbatim snippet already exists in this specific dataset.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:28:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q10", + "question_id": "sample-final-plus-answers-q10", + "exam_id": "sample-final-plus-answers", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "Datetime day-of-year", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives a `timedelta`; taking `.days` and adding 1 makes January 1 equal to day 1. The other options either misuse `timedelta`, add an integer directly to a `datetime` difference, or use an invalid date.", + "code_context": "day_of_year(datetime(2022, 2, 1))\n# should return 32" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 10, + "question_summary": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 10, + "question_summary": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ], + "evidence_topics": [ + "Datetime" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime", + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This snippet is a near-identical exam question that explicitly explains the logic: subtracting two datetimes creates a timedelta, accessing .days gives the integer difference, and adding 1 converts 0-based indexing to the 1-366 range." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly addresses the exact problem with a clear explanation of the underlying mechanics (timedelta and .days attribute)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This single snippet provides the complete conceptual and syntactical solution required for the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippet list contains the exact same question (or a very close variant) along with an explanation that maps directly to option 'a'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent because the database already contains a sample exam question covering this specific datetime application.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:28:46Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q11", + "question_id": "sample-final-plus-answers-q11", + "exam_id": "sample-final-plus-answers", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary comprehension", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Only option A is a dictionary comprehension with each string as the key and its length as the value. The others create a list, a set, or a dictionary with the mapping reversed.", + "code_context": "list_1 = [...]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 11, + "question_summary": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 11, + "question_summary": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This snippet contains the exact same question and options, explicitly identifies 'A' as the correct answer, and defines it as a 'standard dictionary comprehension' while explaining why the other options (list, set) are incorrect." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Directly answers the specific exam question with a clear breakdown of why option A is correct and why B and C are wrong." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Presents an almost identical scenario (list of words to dictionary of lengths) which reinforces the pattern recognition for dictionary comprehension syntax {key: value for ...}." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides additional context on creating dictionaries from existing list data, which helps understand the general relationship between names/keys and ages/values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This single snippet provides the verbatim question, the answer, and the terminology needed to distinguish the correct syntax from the distractors." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question and a detailed explanation of the correct choice. A student with zero knowledge can simply match the 'standard dictionary comprehension' description to the syntax in option A.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the specific question is answered, the general 'rule' of comprehension syntax (brackets vs. braces and the colon) is only implied by the specific examples.", + "missing_concepts": [ + "Explicit syntax rule: {k: v for ...} = Dict, [v for ...] = List, {v for ...} = Set" + ], + "proposed_fix": "Add a summary item that lists the different types of comprehensions and their corresponding bracket/brace syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Comprehension Syntax' summary card: 1. Dictionary: {key: value for item in iterable}, 2. List: [value for item in iterable], 3. Set: {value for item in iterable}.", + "why_helpful": "It allows the student to answer any variation of this question (e.g., 'create a set' or 'create a list') rather than just memorizing this specific instance.", + "why_maybe_unnecessary": "The existing snippets already label the types, which might be enough for a single-question exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:29:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q12", + "question_id": "sample-final-plus-answers-q12", + "exam_id": "sample-final-plus-answers", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Case swapping", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[x if x in 'abcdefghijklmnopqrstuvwxyz'.upper() else x.lower() for x in list_1]", + "c": "Both achieve what you want", + "d": "None achieves what you want" + }, + "correct": "a", + "explanation": "Option A explicitly checks whether each character is lowercase and flips the case accordingly. Option B leaves uppercase letters unchanged instead of converting them to lowercase.", + "code_context": "list_1 = [...]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 12, + "question_summary": "You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-12-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 12, + "question_summary": "You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-12-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-12-w2-conditions", + "exam-intro_python_sample_final_24_25-12-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Directly identifies the 'case swapping' problem and confirms that conditional logic within a list comprehension is the standard approach for this task." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Matches the exact problem statement (flipping upper and lower case letters in a list) and mentions conditional logic." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides context for working with string alphabets and converting strings to lists, relevant for understanding the logic in Option B." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Shows how functions/methods can be applied to string data, reinforcing the concept of string method usage." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Primary topical match." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Helps clarify alphabet string membership used in Option B." + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the best snippet identifies the problem, its rationale ('Both options implement...') actually contradicts the specific logic in this question's Option B (which fails to swap cases). Without knowing '.islower()', a student might be misled by the snippet into choosing the 'Both' option.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets provide the context of 'case flipping' but lack definitions for the boolean method '.islower()' and the ternary list comprehension syntax.", + "missing_concepts": [ + ".islower() string method", + "ternary conditional syntax within list comprehensions", + "Difference between membership testing (in) and boolean checks (islower)" + ], + "proposed_fix": "Add a foundational snippet explaining string inspection methods (.islower, .isupper) and the [x if cond else y for x in list] syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet defining string case methods (.upper(), .lower(), .islower()) and the syntax for 'if-else' logic inside a list comprehension.", + "why_helpful": "Essential for a zero-knowledge student to evaluate why 'islower()' is the correct check vs the 'in alphabet' check used in Option B.", + "why_maybe_unnecessary": "Snippet 12 provides a shortcut, but it's risky due to conflicting rationales between exams.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:29:44Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q13", + "question_id": "sample-final-plus-answers-q13", + "exam_id": "sample-final-plus-answers", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Comparisons and types", + "question": "Suppose you have three variables x, y, z, as follows:\nx = '3'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string `'3'` is not equal to the integer `3`, while `3 == 3.0` is `True`. The chained comparison `x == y == z` means `(x == y) and (y == z)`, so it is `False`.", + "code_context": "x = '3'\ny = 3\nz = 3.0" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 13, + "question_summary": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 13, + "question_summary": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet is a perfect match for the question. It explicitly states that '3' == 3 is False, 3 == 3.0 is True, and explains exactly how the chained comparison x == y == z is evaluated as (x == y) and (y == z)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Directly provides the answer and full logic for the identical question." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Provides the fundamental definitions of Python types (str, int, float, etc.), which helps a student understand why a string '3' differs from the number 3." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Uses the same variable set (x='3', y=3, z=3.0) in a different comparison context, reinforcing how these types interact." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Independently sufficient as it contains the exact logic and explanation for every part of the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains a snippet that is an exact replica of the question with a comprehensive explanation of the comparison rules (type inequality for strings vs numbers, value equality for ints vs floats, and the mechanics of chained comparisons).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps found. The existing snippets cover both the specific instance and the underlying concepts of types and comparisons.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q14", + "question_id": "sample-final-plus-answers-q14", + "exam_id": "sample-final-plus-answers", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Loops", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. (In the first iteration, just take the previous number to be 0.)\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e.: only the sums).", + "options": { + "a": "i = 0\nwhile i <= 10:\n print(i + (i-1))\n i += 1", + "b": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "b", + "explanation": "Option B correctly tracks the previous number and starts the loop at 1, producing the required sums. Option A starts at 0 and prints `-1` on the first iteration, so it does not match the specification.", + "code_context": "# target outputs: 1, 3, 5, ..., 19" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 14, + "question_summary": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops" + ], + "evidence_topics": [ + "Loops" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 14, + "question_summary": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops" + ], + "evidence_topics": [ + "Loops" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops", + "exam-intro_python_sample_final_24_25-14-w2-loops" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "This snippet is a direct match for the question logic, explicitly stating that the program should iterate from 1 to 10, sum current/previous, and that Option B is correct because it updates the 'previous' state correctly." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "Directly explains the logic for this specific sum-of-previous-and-current pattern." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Provides a crucial boundary hint by noting that a loop running while 'i < 11' iterates 'from 1 to 10', helping the student understand the 'range(1, 11)' in the options." + }, + { + "item_id": "ks-bddafc66a0", + "rationale": "Shows the basic for-loop syntax (for variable in sequence), which is fundamental to identifying the structure used in Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "By itself, this snippet essentially provides the answer and the reasoning for the specific logic required." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Clarifies that to get integers up to 10, the range/condition must go up to 11." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-14-w2-loops' describes the exact scenario and logic. Combined with the boundary explanation in 'exam-Test Resit...-4-w2-loops', a student can confidently select Option B.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent because the dataset contains a variant of the exact same question. The only slight difficulty might be understanding the exact behavior of 'range(1, 11)', but one snippet provides a high-level hint for this.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:23Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q15", + "question_id": "sample-final-plus-answers-q15", + "exam_id": "sample-final-plus-answers", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Functions and scope", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "Result is a local name and cannot be referenced outside of the function.", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "`result` is defined inside `cube`, so it exists only within the function scope. The line `print(result)` is outside the function, where that local name is not defined.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 15, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-15-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 15, + "question_summary": "Executing the following program will produce an error. Why?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-15-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-15-w2-conditions", + "exam-intro_python_sample_final_24_25-15-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "This snippet describes the exact scenario from the question (a 'cube' function with a 'result' variable) and explains that it is local and inaccessible from the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Provides a direct, identical example of the error and the correct explanation." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the formal definition of local and global scope, explaining that local names are 'only known inside the function'." + }, + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "rationale": "Reinforces the concept with a similar example ('power' function) and explicitly mentions that 'print(result)' fails because it is called in the global scope." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Directly answers the specific question scenario." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Explains the underlying rule that allows a student to generalize why the error occurs." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets include a near-identical exam question and the precise lecture definition required to understand why a local variable is inaccessible outside its function.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets perfectly cover the 'Scope' concept as it relates to this question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:39Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q16", + "question_id": "sample-final-plus-answers-q16", + "exam_id": "sample-final-plus-answers", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "Lambda functions", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "The first lambda returns `1 + 2 = 3`, the second returns `1 * 2 = 2`, and `3 ** 2` equals `9`.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 16, + "question_summary": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns" + ], + "evidence_topics": [ + "Higher-Order Patterns" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 16, + "question_summary": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns" + ], + "evidence_topics": [ + "Higher-Order Patterns" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "This snippet is an exact match for the question and provides a clear, step-by-step mathematical breakdown of the lambda calls and the final exponentiation result." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "Directly answers the question with the exact same code and values." + }, + { + "item_id": "ks-58858d6d96", + "rationale": "Explains the fundamental syntax of lambda functions (lambda params: expression), which is essential for a student with zero knowledge to understand how the code works." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Reinforces the concept of functions as objects and demonstrates the exponentiation operator (**), which is the final step of the calculation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "Provides the specific solution and mathematical logic." + }, + { + "item_id": "ks-58858d6d96", + "rationale": "Provides the general rule for lambda functions so the student can parse the code structure." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The collection includes the identical exam question and answer key, along with a lecture snippet explaining the underlying syntax.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover both the specific instance and the general syntax. No significant conceptual gaps exist for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:30:58Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q17", + "question_id": "sample-final-plus-answers-q17", + "exam_id": "sample-final-plus-answers", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "Empty-sequence equality chain", + "question": "You have the following function called main:\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat will be printed by the following lines:\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))", + "options": { + "a": "True\nFalse\nFalse", + "b": "False\nFalse\nTrue", + "c": "True\nFalse\nTrue", + "d": "True\nTrue\nTrue" + }, + "correct": "d", + "explanation": "The first call builds [True, True, True], the second call builds [False, False, False], and the third call also builds [False, False, False]. In all three cases the chained equality compares three identical booleans, so each printed result is True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 17, + "question_summary": "What will be printed by the function calls in the main function provided?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 17, + "question_summary": "What will be printed by the function calls in the main function provided?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "rationale": "This snippet appears to be from the exact same question or a near-identical variant, explicitly explaining that the function checks if elements are consistently empty or non-empty." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "rationale": "Directly explains the logic of the problem: checking for empty vs non-empty consistency across multiple calls." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Demonstrates the 'for loop with an if-condition appending to a list' pattern used in the code context." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Provides an example of complex boolean evaluation and comparison logic similar to the chained equality return." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "rationale": "Provides the high-level logic and correct interpretation of the empty sequence checks." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Helps trace the list-building process (y.append)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first recommended snippet describes the exact logic of this specific exam question, noting that empty sets/lists and non-empty sequences are processed consistently within each function call.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is explained, a student with zero Python knowledge might still struggle with the specific behavior of chained equality (y[0] == y[1] == y[2]) and the fact that an empty dictionary {} has a length of 0.", + "missing_concepts": [ + "chained equality behavior (a == b == c)", + "len() results for empty containers like {} and []" + ], + "proposed_fix": "Add a foundational snippet explaining common sequence lengths and the chained comparison operator." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Sequence Properties' card showing that len([]) == 0, len({}) == 0, and len('') == 0, and explaining that a == b == c is only True if all three are identical.", + "why_helpful": "It bridges the gap for absolute beginners who might not know {} is a dictionary or that comparisons can be chained in Python.", + "why_maybe_unnecessary": "The existing 'intro_python_sample_final' snippet already hints at this logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:31:16Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q18", + "question_id": "sample-final-plus-answers-q18", + "exam_id": "sample-final-plus-answers", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "List chunking into sublists", + "question": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nFor example:\nIf you have the original list x as:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nHow do you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:(i + 3)] for i in range(0, 7, 3)]", + "b": "y = [x[i[0]::3] for i in enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "a", + "explanation": "Option A slices the list in chunks of length 3 starting at indices 0, 3, and 6, which produces the three required sublists in order.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 18, + "question_summary": "How do you break a list into a list of lists, where each sublist contains 3 elements?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-18-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 18, + "question_summary": "How do you break a list into a list of lists, where each sublist contains 3 elements?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-18-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-18-w2-conditions", + "exam-intro_python_sample_final_24_25-18-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "This snippet is a direct match for the question, providing the exact code for Option A and explaining how the range function and slicing work together to partition the list." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Directly answers the exam question and explains the logic of the correct option." + }, + { + "item_id": "aiq-3", + "rationale": "Provides a clear manual breakdown of how range(start, stop, step) generates values, which is essential for understanding the indices 0, 3, and 6." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Introduces the concept of list slicing (start:stop:step), which helps a student understand the x[i:i+3] syntax used in the answer." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Contains the specific problem, the correct answer, and the underlying logic." + }, + { + "item_id": "aiq-3", + "rationale": "Explains the range function logic used to generate the chunk starting points." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One candidate snippet contains the exact same question and explains the correct answer. Combined with a breakdown of the range function, a student with no prior knowledge can verify why 'a' is correct.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the solution and the range logic, but do not explicitly explain the 'List Comprehension' syntax (the [x for x in list] structure).", + "missing_concepts": [ + "List comprehension syntax" + ], + "proposed_fix": "Add a small snippet or AI example explaining that [expression for item in iterable] is a way to build a list by repeating an action." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "List Comprehension: [expression for item in iterable] creates a new list by running the expression for every item. Example: [i*2 for i in range(3)] generates [0, 2, 4].", + "why_helpful": "It helps students understand that the brackets in the answer aren't just for a list, but are a loop that generates sublists.", + "why_maybe_unnecessary": "The student might infer the behavior from the direct-match snippet provided in the exam-intro snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:31:33Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q19", + "question_id": "sample-final-plus-answers-q19", + "exam_id": "sample-final-plus-answers", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary running totals", + "question": "You have to write a function called main that accepts a dictionary as an input argument.\nBoth the keys and the values of the input are integers.\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary whose keys are smaller than or equal to the output key in question.\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "b": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "c": "Both of the above work as intended", + "d": "None of the above works as intended" + }, + "correct": "c", + "explanation": "The first program computes each output value by summing all input values whose keys are less than or equal to the current key. The second program accumulates values in ascending key order, which yields the same running totals for each key.", + "code_context": "main({5: 1, 2: 5, 4: 2})\n# expected result:\n# {5: 8, 2: 5, 4: 7}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 19, + "question_summary": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 19, + "question_summary": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "This snippet is a direct match for the question logic. It explicitly mentions calculating cumulative sums where keys are <= the output key and confirms that both methods (Option C) are correct, even noting that one is more efficient." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "Directly identifies the 'running totals' logic and confirms that both common implementations (list comprehension vs. sorted loop) work." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the basic pattern of iterating over a collection to populate a dictionary, which helps understand the 'result[key] = ...' structure." + }, + { + "item_id": "aiq-5", + "rationale": "Shows the usage of the sum() function and returning a dictionary, which are core components of the code in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "Provides the conceptual answer and confirms the validity of the two approaches described in the question options." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet in the candidate list is effectively a summary of this exact exam question. It describes the goal (cumulative sums based on keys <= current key) and identifies the correct answer as 'Both methods' (C).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the best snippet gives the answer directly, the supporting snippets do not explicitly explain 'list comprehensions' or the 'sorted()' function for a student with zero knowledge who wants to verify the code themselves.", + "missing_concepts": [ + "List comprehensions (for Option A)", + "Dictionary iteration using .items()", + "The effect of sorted() on dictionary keys" + ], + "proposed_fix": "Add a snippet that demonstrates a list comprehension inside a loop or a comparison of dictionary iteration methods." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet explaining 'Sorted Dictionary Iteration': 'To process a dictionary in order of its keys, use `for key in sorted(my_dict.keys()):`. This ensures you visit keys from smallest to largest, which is useful for calculating running totals.'", + "why_helpful": "It directly explains the logic behind Option B, which is often the more confusing part of this specific question for beginners.", + "why_maybe_unnecessary": "The 'best' snippet already tells the student that both options work, which might be enough for a 'cheat sheet' context.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:31:54Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q20", + "question_id": "sample-final-plus-answers-q20", + "exam_id": "sample-final-plus-answers", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary equality with zip and enumerate", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) produces key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same key-value pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 20, + "question_summary": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 20, + "question_summary": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "This snippet is a direct match for the question logic, explicitly stating that d1 (from zip) and d2 (from enumerate) result in the same dictionary." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Provides the direct answer and the final dictionary state for both constructions." + }, + { + "item_id": "ks-65c4de2e9d", + "rationale": "Explains dictionary equality (unordered) and the basic structure of key:value pairs." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows a concrete example of a dictionary structure {1: 10, ...} which helps a novice visualize what d1 and d2 look like." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Directly identifies that zip and enumerate produce the same dictionary in this context." + }, + { + "item_id": "ks-65c4de2e9d", + "rationale": "Confirms that comparing two dictionaries with '==' checks if they contain the same key-value pairs regardless of order." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question and its solution are present in the exam-intro_python_sample_final snippet.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is directly provided by one snippet, there is a lack of fundamental explanation for how 'zip' and 'enumerate' work independently.", + "missing_concepts": [ + "Explicit definition of zip(list1, list2) pairing behavior", + "Explicit definition of enumerate(list, start) index-value pairing" + ], + "proposed_fix": "Add a lecture-based snippet (ks) that defines zip and enumerate mechanics for general list processing." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'zip(l1, l2) creates pairs of elements from two lists at the same index. enumerate(l, start) creates pairs of (index, element), where the index starts at the specified value (default 0).'", + "why_helpful": "It allows a student to derive the answer logically if the lists or indices were modified, rather than relying on a memorized exam answer.", + "why_maybe_unnecessary": "The direct exam match already provides the answer for this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:32:14Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q21", + "question_id": "sample-final-plus-answers-q21", + "exam_id": "sample-final-plus-answers", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary iteration semantics", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not (key, value) pairs, so `for key, value in d1:` is invalid. The other three variants all sum the dictionary values correctly.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 21, + "question_summary": "The following codes all print the same value, except one. Which one?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 21, + "question_summary": "The following codes all print the same value, except one. Which one?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "This is an exact match for the question, providing both the problem statement and the explicit explanation that iterating directly over a dictionary yields keys, leading to a ValueError if unpacking into two variables." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Directly answers the specific question and explains the error in option A." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Provides the general rule for dictionary iteration: .keys() for keys, .values() for values, and .items() for (key, value) pairs, which covers the underlying logic for all options." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the use of .values() and .keys() in a practical code snippet, reinforcing the syntax used in options B, C, and D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Contains the exact question and the 'why' behind the correct answer." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Supplies the conceptual framework for understanding how to correctly iterate over keys, values, or pairs." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes the exact exam question from a previous year along with a lecture snippet that explains the relevant semantics of dictionary looping.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps found; the provided snippets cover both the specific instance and the general principle.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:32:29Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q22", + "question_id": "sample-final-plus-answers-q22", + "exam_id": "sample-final-plus-answers", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "String count method", + "question": "You have the following string\nx = 'Amsterdam'\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method `count` must be called on the string object itself. `x.count('a')` returns 1 for the lowercase 'a' in 'Amsterdam'.", + "code_context": "x = 'Amsterdam'" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 22, + "question_summary": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 22, + "question_summary": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions", + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "This snippet contains the exact question and explains that .count() is a string method requiring dot notation on a string object, directly answering why option B is correct." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Directly addresses the question and provides the specific syntax rule for the count method." + }, + { + "item_id": "ks-ab66f3bab6", + "rationale": "Explains the fundamental difference between methods (attached to objects) and functions, which is the core concept being tested." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Sufficient on its own as it provides both the answer and the explanation for this specific problem." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet is a near-perfect match for the exam question and provides the necessary syntax explanation for a novice to identify the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets perfectly cover the syntax of calling a method. However, they don't explicitly mention string case-sensitivity (why Amsterdam has only one 'a'), which is part of the question's logic.", + "missing_concepts": [ + "String case-sensitivity in Python", + "Standard string method definitions (count, find, replace)" + ], + "proposed_fix": "Add a lecture snippet or knowledge card specifically covering common string methods and their case-sensitive nature." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet detailing that Python string methods like .count(), .find(), and .index() are case-sensitive by default (e.g., 'A' != 'a').", + "why_helpful": "It ensures the student understands why the answer is 1 and not 2, reinforcing the logic behind the specific example provided in the question.", + "why_maybe_unnecessary": "The syntax rule (dot notation vs function call) is the primary hurdle for the question, which is already covered.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:32:47Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q23", + "question_id": "sample-final-plus-answers-q23", + "exam_id": "sample-final-plus-answers", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "Higher-order function returning 30", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "The first call returns (1+5)+(2+5)+(3+5)+(4+5)=30, and the second returns 1^2+2^2+3^2+4^2=30. Both produce the requested result.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 23, + "question_summary": "Which of the following function calls would return the number 30 as a result?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 23, + "question_summary": "Which of the following function calls would return the number 30 as a result?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ], + "evidence_topics": [ + "Arguments" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments", + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "This snippet is a direct match for the question and explicitly provides the arithmetic breakdown (6+7+8+9=30 and 1+4+9+16=30) for both function calls." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Provides the direct answer and calculation logic for the exact question." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Helps a student understand the concept of passing functions (like square/cube) as arguments to another process." + }, + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "rationale": "Explains the *args syntax, which is necessary to understand how multiple numbers (1, 2, 3, 4) are being handled by the calculation function." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Contains the full logic and verification for both options presented in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The first snippet contains the exact question and its solution. Even without knowing Python, a student can match the numbers and the sum result (30) from the snippet text.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The direct answer is present, but the underlying concept of 'lambda' is only implicitly explained via the arithmetic results.", + "missing_concepts": [ + "Explicit lambda syntax definition (lambda parameters: expression)" + ], + "proposed_fix": "Add a dedicated snippet or AI common question that briefly defines lambda as a 'mini-function on one line' to bridge the gap between seeing the code and performing the math." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Lambda Basics' that explains: 'lambda x: x + 5' means 'take x and add 5 to it'.", + "why_helpful": "It allows the student to perform the calculation themselves rather than just relying on matching the search text of a previous exam question.", + "why_maybe_unnecessary": "The existing sample final snippet already performs the calculation for the student.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:33:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:sample-final-plus-answers-q24", + "question_id": "sample-final-plus-answers-q24", + "exam_id": "sample-final-plus-answers", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "Circle area imports and aliases", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C aliases the module as `constants`, so `math.pi` is not defined there. The other three options reference pi correctly.", + "code_context": "# area formula\n# pi * r ** 2" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 24, + "question_summary": "Which script does NOT print the correct answer for the area of a circle?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-24-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + }, + { + "question_number": 24, + "question_summary": "Which script does NOT print the correct answer for the area of a circle?", + "score": 3, + "evidence_item_ids": [ + "exam-intro_python_sample_final_24_25-24-w2-conditions" + ], + "evidence_topics": [ + "Conditions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "Exact selectable source_exam item for this question exists in the current builder corpus.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-intro_python_sample_final_24_25-24-w2-conditions", + "exam-intro_python_sample_final_24_25-24-w2-conditions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This snippet is a direct match for the question, providing the exact answer (C) and explaining that aliasing a module with 'as' makes the original module name unavailable in the namespace." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "Directly answers the question and explains the mechanics of module aliasing." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Demonstrates the use of the exponentiation operator (**), which is used in the area formula (r ** 2)." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains the basic print function, which is used to output the result in all options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This single snippet contains the identical question, the correct answer, and a full explanation of the logic." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains the exact question and explanation from a sample final exam, making the answer trivial to find.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps exist because the exact question is present in the source materials.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:33:18Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round1/trial-final-exam-solutions-introduction-to-python-3077951.json b/data/vision_exam_pipeline/work_packets/evaluations/round1/trial-final-exam-solutions-introduction-to-python-3077951.json new file mode 100644 index 0000000..5091a12 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round1/trial-final-exam-solutions-introduction-to-python-3077951.json @@ -0,0 +1,1998 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T19:45:32Z", + "round": "round1", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q01", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q01", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "6-OOP-1", + "question": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor, then the \"mode\" attribute should be equal to \"land\".\n\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A defines an initializer with a required vehicle name and a default mode of \"land\", then stores both on the instance using self.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 1, + "question_summary": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction. The \"name\" attri", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-init-default", + "rationale": "This snippet explicitly addresses the core concept of the question: using default values in the `__init__` constructor (e.g., `vehicle_mode='land'`) to make arguments optional." + }, + "top_three_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Directly explains the syntax for optional constructor arguments and default values required for the 'mode' attribute." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Contains the exact problem statement, allowing a student to recognize the question and apply the relevant concept." + }, + { + "item_id": "aiq-4", + "rationale": "Reinforces the concept of required vs flexible arguments, which helps in understanding how 'name' and 'mode' interact in the constructor." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-init-default", + "rationale": "Explains the default value mechanic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the specific context/requirements." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The 'manual-init-default' snippet provides the exact code pattern (class definition, __init__ method, and default parameter value) needed to identify Option A as correct.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover the 'default value' mechanic well, but don't explicitly explain why Option D (missing 'self') or Option C (using 'return') are incorrect for constructors.", + "missing_concepts": [ + "The role of 'self' as the first parameter in instance methods", + "The fact that __init__ should not return values" + ], + "proposed_fix": "Add a snippet explaining basic class structure and the necessity of 'self' for attribute assignment." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: OOP Fundamentals. Content: In Python, `__init__` is used to set attributes on a new object. Use `self.attribute_name = value`. Always include `self` as the first parameter. Example: `class MyClass: def __init__(self, val): self.val = val`", + "why_helpful": "This helps the student eliminate Option D (missing self) and Option C (incorrectly using return instead of self assignment).", + "why_maybe_unnecessary": "Option A is the only one showing both the correct default value syntax AND self-assignment, so the existing snippets might be enough to guess correctly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:33:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q02", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q02", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "6-OOP-2", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The reviews are 5, 3, and 3, so the average is 11 / 3 = 3.666..., which show_rating rounds to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 2, + "question_summary": "Take a look at the following class definition. Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Ric", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals" + ], + "evidence_topics": [ + "OOP Fundamentals" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This snippet provides a near-perfect structural and logical mirror of the question. It explicitly demonstrates how to 'Trace self state across multiple method calls' using a list of scores and calculating an average with sum() and len()." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Explains the core logic of maintaining state in a list and calculating a numerical average within a class method." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Directly matches the exam question, allowing the student to see the exact scenario and options they are likely to encounter." + }, + { + "item_id": "kp-manual-init-defaults-d2", + "rationale": "Clarifies the specific 'review_scores=None' to '[]' initialization pattern used in the question's constructor, which is a common source of confusion for beginners." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Covers the internal logic of the method calls and averaging." + }, + { + "item_id": "kp-manual-init-defaults-d2", + "rationale": "Covers the initialization logic for the mutable list attribute." + }, + { + "item_id": "ks-06b21ad349", + "rationale": "Provides the foundational context that a class is a 'blueprint' and __init__ is the constructor." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Between the exact question match and the AI-generated logic mirror, a student can easily connect the pattern of adding items to a list and then calculating an average. The only minor leap is the round() function.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage for OOP state management and list manipulation is excellent. The only missing element is an explicit definition of the built-in round() function's behavior with the second argument.", + "missing_concepts": [ + "The round(number, ndigits) built-in function" + ], + "proposed_fix": "Add a snippet explaining common math built-ins like round(), especially highlighting how the second argument controls decimal precision." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point: 'The round(value, n) function rounds a number to n decimal places. Example: round(3.6666, 1) results in 3.7.'", + "why_helpful": "The question requires choosing between 3.7 and 3.67; knowing how the '1' in round(..., 1) works is the final step to the correct answer.", + "why_maybe_unnecessary": "The term 'round' is intuitive enough for many students to guess the behavior correctly given the options.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:34:07Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q03", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q03", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "6-strings-1", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\n\nFor example, if:\nstudents = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 7.5.\nBernard has received a grade of 8.0.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']:.1f}.\")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {grade:.1f}.\")", + "c": "for student in students:\n print(f\"{student[\\\"Name\\\"]} has received a grade of {student[\\\"Grade\\\"]:.1f}.\")", + "d": "for student, grade in students:\n print(f\"{student} has received a grade of {grade:.1f}.\")" + }, + "correct": "a", + "explanation": "Option A iterates through each dictionary in the list and formats the student's name and grade correctly to one decimal place. The other options use the wrong iteration pattern or invalid access pattern for this data structure.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 3, + "question_summary": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary in the students list has two keys: \"Name\" and \"Grade\". The correspondi", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ], + "evidence_topics": [ + "Objects and Names" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is a near-exact match of the current question, including the specific requirement for displaying grades to one decimal place, allowing a student to identify the pattern immediately." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Matches the question prompt and constraints (list of dictionaries, f-string rounding) perfectly." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Another exact match of the problem scenario (students list with Name/Grade dictionaries)." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides context on iterating through lists to create or access dictionaries, which helps clarify why list iteration (Option A) is correct over dict.items() (Option B)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Matches the exact question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Matches the exact question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact question from previous exam iterations. A student can match the 'students' list and 'one decimal place' requirement directly to the resources.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exact question exists in the bank, there is a lack of a generalized 'F-String Formatting Cheat Sheet' that explains the syntax for rounding floats (e.g., .1f), which would help a student understand *why* the answer is correct rather than just pattern matching.", + "missing_concepts": [ + "f-string float precision syntax (:.nf)", + "difference between list iteration and dictionary .items() iteration" + ], + "proposed_fix": "Add a dedicated key point or subtopic detail specifically for 'String Formatting with F-Strings' that explicitly demonstrates float rounding." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Key Point: F-String Float Formatting. Syntax: f'{value:.1f}' rounds to 1 decimal place. Example: price = 5.0; print(f'{price:.2f}') outputs 5.00.", + "why_helpful": "This provides the underlying logic for rounding, which is a core part of the question's 'distractor' logic (ensuring the student knows how to get 7.5 instead of 7.500000).", + "why_maybe_unnecessary": "Since the exact question is already in the database, the student might just copy the answer without needing the rule.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:34:30Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q04", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q04", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "6-strings-2", + "question": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character, at various places).\n\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A does not work because strings are immutable and number.replace(\"-\", \"\") returns a new string that is ignored. The function then returns the original unmodified number.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# all should return \"0205251400\"" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 4, + "question_summary": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argum", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ], + "evidence_topics": [ + "Defining and Calling Functions" + ], + "evidence_buckets": [ + "additional" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "This snippet explicitly states that 'Strings in Python are immutable' and that '.replace() returns a new string but does not modify the original,' which directly explains why Option A is the code segment that fails." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Provides the direct conceptual and specific explanation for the failure of the replace method in Option A." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Contains the full problem description for the 'format_phone_number' task, providing necessary context." + }, + { + "item_id": "aiq-2", + "rationale": "Introduces the important concept of whether a method 'mutates the list in place,' helping the student distinguish between in-place mutation and returning a new object." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "Contains the exact logic needed to identify Option A as the incorrect implementation." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-4-w2-conditions' contains the verbatim explanation and rationale for the correct answer, specifically addressing string immutability and the behavior of the .replace() method.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available snippets provide both the problem context and the specific technical explanation required to answer the question correctly.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:34:56Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q05", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q05", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-new_column-1", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] + df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x + df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\" + \"B\"]", + "d": "df[\"C\"] = df[\"A\" + \"B\"]" + }, + "correct": "a", + "explanation": "Option A performs elementwise addition between columns A and B and stores the result in column C. The other options either misuse map, index into the columns object incorrectly, or look for a non-existent combined column name.", + "code_context": "df has numeric columns \"A\" and \"B\"; column \"C\" should contain their sum." + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 5, + "question_summary": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers. You'd like to create a column called \"C\", which contains the sum of", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ], + "evidence_topics": [ + "Pandas Core Structures" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "This snippet contains the exact question and specifically mentions 'Vectorized addition in Pandas', which explains the logic required to identify option A as the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Directly matches the question and provides the concept of vectorized addition." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "An exact replica of the question text from a different exam source." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Demonstrates the syntax for mathematical operations between Pandas structures to create a new Series/column." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides both the solution and the technical rationale for why the operation works." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets contain the exact exam question and its correct answer, making it trivial for a student to answer correctly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the specific answer to this question but lack a general conceptual rule about the syntax of Pandas column assignment.", + "missing_concepts": [ + "General syntax for DataFrame column creation (df['new'] = expression)", + "Explicit definition of element-wise (vectorized) operations versus scalar operations" + ], + "proposed_fix": "Add a foundational 'Pandas Key Point' snippet that generalizes the pattern: 'To create a new column based on others, use the syntax: df[\"New\"] = df[\"Col1\"] + df[\"Col2\"]'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a conceptual snippet explaining 'Pandas Column Arithmetic' that shows how df['C'] = df['A'] + df['B'] performs a row-by-row sum and stores it in 'C'.", + "why_helpful": "It helps the student understand the 'why' and apply the knowledge to variations (e.g., subtraction or multiplication) rather than just memorizing one specific question.", + "why_maybe_unnecessary": "The student can already answer this exact question because it is duplicated in the exam snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:35:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q06", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q06", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-selection-1", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that only contains those elements of column \"B\" in df that have an even-numbered index. Which of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters rows whose index is even and selects column B while keeping the result as a DataFrame by using [[\"B\"]]. Option D would return a Series, not a DataFrame, and the other options do not select the requested data correctly.", + "code_context": "df printed as:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2" + }, + "seed_context": { + "exact_match_findings": [ + { + "question_number": 6, + "question_summary": "You have a pandas DataFrame called df that looks like this, when printed: A B C D 1 9.1 9.5 9.0 6.0 2 6.4 8.2 7.5 1.7 3 2.5 5.3 8.8 3.0 4 6.7 3.6 7.2 6.9 5 8.4 1.9 8.2 3.3 6 8.1 8.", + "score": 3, + "evidence_item_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ], + "evidence_topics": [ + "Inspecting and Selecting Data" + ], + "evidence_buckets": [ + "recommended" + ], + "rationale": "This exact practice-exam question is already available as a selectable exam snippet in the builder.", + "ai_summary_would_help": false, + "ai_summary_note": "" + } + ], + "available_seed_snippet_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet provides the exact reasoning required: it explains that Option A is correct because it uses a boolean mask on the index for even numbers and specifies ['B'] as a list to ensure the result is a DataFrame." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Contains the explicit logic for the correct answer, including the mask and the list-selection for DataFrame output." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Matches the exact question text and data table provided in the prompt, providing perfect context." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Explains the [start:stop:step] slicing syntax (1::2), which helps a student understand why Option D (2::2) might be tempting but potentially incorrect compared to the boolean mask." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides the 'why' for the correct answer." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides the 'what' (the specific problem setup)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets contain an identical question and a clear explanation of the specific syntax nuances (boolean mask vs slicing, and Series vs DataFrame return types).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are highly effective. The only minor issue is a metadata mismatch where a key Pandas snippet is tagged with 'string-operations'.", + "missing_concepts": [ + "Explicit difference between .loc slicing (which returns a Series if a single string is passed) and list-passing (which returns a DataFrame)." + ], + "proposed_fix": "Ensure snippets explaining .loc explicitly contrast df.loc[rows, 'col'] vs df.loc[rows, ['col']]." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "proposal": "Update the 'topic' from 'string-operations-and-methods' to 'Inspecting and Selecting Data' or 'Pandas Indexing'.", + "why_helpful": "The current tag is misleading as the content is about Pandas DataFrame selection, not string manipulation.", + "why_maybe_unnecessary": "The search_text is already accurate and will be found by the RAG system regardless of the label.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:35:43Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q07", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q07", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-sorting-1", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\n\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False)[[\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A sorts the entire DataFrame by index in descending order and would include rows 5 and 1 as well, so it would not match df2. The other options all produce rows 4, 3, and 2 with columns A, C, and D.", + "code_context": "print(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This snippet contains the exact logic and explanation for why Option A is the correct answer to this specific question, explicitly stating that sort_index would result in a 5-row DataFrame instead of the required 3 rows." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Provides the direct answer and logic for the specific question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Shows a similar Pandas DataFrame structure and selection context." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces the context of Pandas DataFrame column operations." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This snippet alone provides the solution and the reasoning required to identify the correct choice." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One of the candidate snippets is an exact match for the question and explanation, making the answer clear even to a student with no prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the direct answer but lack general definitions for the specific Pandas methods used in the alternative (incorrect) options.", + "missing_concepts": [ + "Explicit difference between .loc (label-based, inclusive) and .iloc (position-based, exclusive)", + "Behavior of .sort_values vs .sort_index in Pandas" + ], + "proposed_fix": "Add a snippet explaining the syntax and slicing rules for .loc and .iloc to help students verify options B, C, and D." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a foundational snippet explaining that .loc[2:4] includes labels 2, 3, and 4, whereas .iloc[[3, 2, 1]] selects the 4th, 3rd, and 2nd rows respectively.", + "why_helpful": "This allows the student to understand why the other options (B, C, D) *could* have created df2, rather than just knowing why A could not.", + "why_maybe_unnecessary": "The direct explanation for Option A in the existing snippet is already sufficient to select the right answer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:36:15Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q08", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q08", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-string-1", + "question": "There is a pandas Series called s, which contains Dutch municipality and corresponding province names, separated by a semicolon and a whitespace. The following, for example, is an element of this Series: \"Amsterdam; Noord-Holland\".\n\nYou'd like to create a new Series that only contains the municipality names from s in the same order. Which of the following code lines will achieve what you want?", + "options": { + "a": "s.map(lambda x: x.split(\"; \")[0])", + "b": "s.split(\"; \")[0]", + "c": "s.lambda(x.split(\"; \"))", + "d": "s.str[:9]" + }, + "correct": "a", + "explanation": "Option A applies split('; ') to each element in the Series and takes the first part, which is the municipality name. The other options either do not operate elementwise or do not reliably extract the municipality name.", + "code_context": "Example element in s:\n\"Amsterdam; Noord-Holland\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet describes the exact scenario of a Series 's' with municipality and province names separated by '; ' and explicitly identifies the '.map()' method as the solution for applying a function like split." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly matches the question scenario and explains the use of the .map() method for elementwise transformation." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides a conceptual example of creating a new Series from an existing one based on a calculation (square of difference), reinforcing the 's.operation' pattern." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions splitting strings based on separators (dashes in this case), which helps a student understand what the 'split' part of the correct option does." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet is independently sufficient as it contains the exact problem statement and identifies '.map()' and 'split' as the mechanics for the solution." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The best snippet is a near-perfect match for the question text and directly names the required method (.map) and logic (split).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the direct match is excellent, there is no explanation of 'lambda' syntax or how '[0]' indexes the result of a split.", + "missing_concepts": [ + "lambda syntax", + "indexing split results" + ], + "proposed_fix": "Add a snippet explaining that 'lambda x: x.split(...)[0]' is a concise way to take the first part of every string in a collection." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "proposal": "Expand the snippet text to include the full logic: 'The .map(lambda x: x.split(\"; \")[0]) method allows applying the split function to each element and taking the first part.'", + "why_helpful": "The current text cuts off at '(like spli'. Showing the full code ensures a student can confidently identify Option A without guessing 'lambda' syntax.", + "why_maybe_unnecessary": "The current text is already highly suggestive of the correct answer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:36:41Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q09", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q09", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-1", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "\"03/02/2013\" matches %m/%d/%Y and gives month 3, \"03.02.2013\" matches neither branch and becomes None, and \"03-02-2013\" matches %d-%m-%Y and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This snippet is a direct match for the question and includes an explanation of how the different date formats are parsed and which components correspond to the month." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Directly explains the logic of the code and the resulting values for each input string." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Helps a beginner understand the general structure of a function that iterates through a list and returns a new list based on conditions." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Provides context on how function calls and returns work in Python, helping trace the execution." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "Contains the exact code logic and explains the interpretation of the strptime format codes (%m vs %d)." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains the exact question with an explanation that breaks down the code's behavior for each input string.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective because one of them is a perfect match for the question. A minor gap exists in providing a general reference for datetime format codes.", + "missing_concepts": [ + "General table of datetime.strptime format codes (e.g., %m, %d, %Y, %b)" + ], + "proposed_fix": "Add a summary card or 'cheat sheet' snippet specifically for Datetime format directives." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a reference snippet for Datetime format strings: %Y (4-digit year), %y (2-digit year), %m (month), %d (day), %H (hour), %M (minute), %S (second).", + "why_helpful": "This would allow a student to solve any datetime parsing question, even if the specific question isn't in the database.", + "why_maybe_unnecessary": "The specific exam question snippet already provides the necessary interpretation for this particular task.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:36:59Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q10", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q10", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-2", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives the zero-based offset in days, and adding 1 converts it to the day number within the year. The other options either return or manipulate timedeltas incorrectly or use an invalid date.", + "code_context": "Example target behavior:\nday_of_year(datetime(2022, 2, 1))\n# returns 32" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This snippet explicitly explains the logic required: subtracting two datetime objects yields a timedelta, and the '.days' attribute must be accessed to get an integer difference." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly explains the relationship between datetime subtraction, timedelta objects, and the .days attribute." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Helps a zero-knowledge student recognize the basic 'def function_name(argument):' syntax used in the options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Provides the specific technical knowledge (timedelta and .days) to distinguish the correct answer from the distractors." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The sample final snippet contains a search text that almost perfectly mirrors the question's logic, explaining that subtraction results in a timedelta and that .days provides the integer needed.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover the core logic (timedelta/days), but don't explicitly state that datetime days must be 1-indexed (invalidating option D's day=0) or that you can't add an integer to a timedelta object directly (invalidating option B/C more strictly).", + "missing_concepts": [ + "datetime constructor constraints (day range 1-31)", + "timedelta arithmetic restrictions (cannot add int to timedelta)" + ], + "proposed_fix": "Add a small reference snippet or 'AI Common Question' about basic datetime and timedelta arithmetic rules." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining that 'datetime(year, month, day)' requires day to be at least 1, and that you cannot directly add an integer to a timedelta object (you must add another timedelta or convert to int first).", + "why_helpful": "It would allow a student to systematically eliminate options B, C, and D rather than just identifying A as plausible.", + "why_maybe_unnecessary": "The current 'best snippet' is so similar to the correct answer that most students will pick A regardless.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:37:22Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q11", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q11", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "8-dict_comprehension-1", + "question": "You have a list of strings called list_1, in which every element is unique.\n\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the dictionary comprehension that maps each string to its length. Option B creates a list, option C creates a set, and option D reverses the intended key-value relation.", + "code_context": "list_1 contains unique strings." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This snippet contains the exact same question text and explicitly identifies Option A as the correct answer, explaining that it is a standard dictionary comprehension." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Directly matches the question text and provides the correct answer with a brief explanation of the comprehension types." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Presents a functionally identical problem (mapping a list of strings to their lengths) and confirms Option A as the solution." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides additional context on creating dictionaries from existing list data, reinforcing the mapping concept." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Literal match for the question; sufficient on its own to identify the answer." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include a verbatim match for the exam question, including the options and the correct answer designation.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are excellent because they contain the exact question or identical logic. No gaps identified for this specific question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:37:38Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q12", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q12", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "8-list_comprehension-1", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\n\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[letter.upper() for letter in list_1 if letter.islower() else letter.lower()]", + "c": "[letter.lower() for letter in list_1 if letter.isupper()] + [letter.upper() for letter in list_1 if letter.islower()]", + "d": "[letter.capitalize() for letter in list_1 if not letter.iscapitalized()]" + }, + "correct": "a", + "explanation": "Option A flips the case of each letter while preserving the original order of the list. The other options either have invalid comprehension syntax, change the order, or use a non-existent string method.", + "code_context": "list_1 contains letters with mixed case." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "This snippet describes the exact same problem (flipping letter case in a list) and confirms that conditional logic within a code line is the correct approach, making it an almost direct answer key." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Direct conceptual match for the problem statement and mentions the use of conditional logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Mentions checking upper/lower case versions of letters, providing context that case sensitivity is a standard consideration in these types of problems." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "Provides the necessary confirmation that case flipping in lists is a known problem solvable with conditional comprehension logic." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The best snippet is a direct analog of the question, providing both the goal and the logic (conditional comprehension) required to solve it. A student can match the 'flip case' intent directly to the snippet's description.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the snippet confirms the logic, it doesn't explicitly display the syntax pattern [X if condition else Y for item in list] vs [X for item in list if condition else Y], which is the primary technical distractor (Option A vs B).", + "missing_concepts": [ + "explicit ternary conditional syntax in list comprehensions" + ], + "proposed_fix": "Add a lecture snippet or reference card that explicitly shows the syntax for list comprehensions with if-else clauses (transformation) vs if-only clauses (filtering)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A syntax reference card for list comprehensions showing: 1. [f(x) for x in list if cond] (filtering) vs 2. [f(x) if cond else g(x) for x in list] (transformation).", + "why_helpful": "The question's main challenge is the syntax placement of the 'if-else' (Option A vs B). A direct syntax guide would make the choice trivial for a non-Python user by showing that 'if-else' must come before the 'for' keyword.", + "why_maybe_unnecessary": "The existing exam snippet already points to 'conditional logic' which might be enough for an intuitive student to pick the only syntactically plausible option (A).", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:38:09Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q13", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q13", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Basic logic", + "question": "Suppose you have three variables x, y, z as follows:\n\nx = 'x'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string 'x' is not equal to the integer 3 or the float 3.0, so the first and third comparisons are False. The integer 3 and float 3.0 are equal in Python, so the second comparison is True. The chained comparison is False because x == y is False.", + "code_context": "x = 'x'\ny = 3\nz = 3.0\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet is a near-perfect match for the question logic. Its explanation explicitly details the rules for string vs. number comparisons, integer vs. float equality (3 == 3.0), and the exact decomposition of chained comparisons (x == y == z)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Directly explains every component of the question's logic, including type-mismatch comparisons and chained equality." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Reinforces the concept that int 3 and float 3.0 are equal (x == y) while strings are not (x != z), providing a secondary example of the same cross-type comparison rules." + }, + { + "item_id": "aiq-5", + "rationale": "Useful for understanding how variables are assigned and compared across different types (int, float, string) in a multi-variable scenario." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This snippet alone provides all three necessary rules: 1. 'str' == 'int/float' is False. 2. 'int' == 'float' is True if values match. 3. 'a == b == c' is evaluated as '(a == b) and (b == c)'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-13-w1-objects-and-names' contains an explanation that explicitly answers the exact logic required for all four lines of the code in the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets are excellent, especially the sample final snippet which covers the chained comparison logic which is usually the hardest part for beginners.", + "missing_concepts": [ + "Explicit definition of types (str, int, float) would be helpful as a reference, though the behavior is clear from the examples." + ], + "proposed_fix": "Add a summary card covering cross-type equality rules and chained comparison evaluation." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Conceptual Card: 'Comparison Rules by Type'. Rule 1: Integers and Floats are equal if they represent the same number (e.g., 3 == 3.0 is True). Rule 2: Strings are never equal to numbers (e.g., '3' == 3 is False). Rule 3: Chained comparisons (a == b == c) are treated as (a == b) AND (b == c).", + "why_helpful": "It abstracts the logic from the exam snippets into a clear set of rules that a student can apply to any similar question.", + "why_maybe_unnecessary": "The explanation in the sample final exam snippet already provides this information, though in a question-specific context.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:38:43Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q14", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q14", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Basic loop", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. In the first iteration, just take the previous number to be 0.\n\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e. only the sums).", + "options": { + "a": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "b": "i = 0\nwhile i <= 10:\n print(i + (i - 1))\n i += 1", + "c": "Both of the above", + "d": "Neither of the above" + }, + "correct": "a", + "explanation": "A keeps track of the previous number and prints each sum correctly from 1 + 0 through 10 + 9. B does not use the required previous-value logic and prints the wrong sums.", + "code_context": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "This snippet describes the exact logic and goal of the question (iterating 1-10, summing current and previous) and provides a direct contextual match, even though its internal explanation mistakenly identifies 'Option B' instead of 'Option A'." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "Identifies the core problem pattern and logic requirements." + }, + { + "item_id": "aiq-3", + "rationale": "Explicitly explains that 'stop' is excluded in range(), which is critical for a student to know that range(1, 11) targets the integers 1 to 10." + }, + { + "item_id": "ks-bddafc66a0", + "rationale": "Provides the basic syntax for 'for' loops and shows an example of updating a 'total' variable, which mirrors the 'previous' state-tracking pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "Problem-specific logic." + }, + { + "item_id": "aiq-3", + "rationale": "Understanding the range() function's boundary behavior." + }, + { + "item_id": "ks-bddafc66a0", + "rationale": "Basic for-loop syntax and variable initialization pattern." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the direct problem-match snippet (even with its label typo) and the 'range' explanation provides all the semantic components needed to identify why 'Option A' is correct (it starts at 1, goes to 10, and updates state at the end).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover the specific problem logic and the range boundary. However, the explanation in the best snippet has a typo (referring to B instead of A) which could be confusing for zero-knowledge students.", + "missing_concepts": [ + "Explicit state-tracking (updating a variable like 'previous' at the end of a loop)" + ], + "proposed_fix": "Add or edit a snippet to explicitly explain 'State Variables' in loops: why the update happens at the bottom and how it affects the next iteration." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "proposal": "Correct the snippet text to point to Option A and add a brief trace: 'In iteration 1: i=1, prev=0. After print, prev becomes 1. In iteration 2: i=2, prev=1...'", + "why_helpful": "Prevents confusion caused by the current typo and reinforces the 'state-tracking' mechanic.", + "why_maybe_unnecessary": "The student might infer the logic from the code options regardless of the snippet's letter label.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:39:08Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q15", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q15", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Basic scope", + "question": "Executing the following program will produce an error. Why?\n\ndef cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "options": { + "a": "Result is a local variable and cannot be referenced outside of the function", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "result is created inside the function, so it is local to cube and is not available at the top level where print(result) is executed.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "This snippet is a near-perfect match for the question, explicitly mentioning the 'cube' function and the variable 'result', and explaining that it cannot be accessed from the global scope." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Directly matches the specific code context (cube function, result variable) and logic of the question." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the formal conceptual rule for local vs. global scope, explaining that names defined inside a function are only known inside that function." + }, + { + "item_id": "manual-local-name", + "rationale": "Offers a clear, simple example showing that names (parameters or locals) fail when printed outside the function body." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Provides the direct answer to the identical pattern." + }, + { + "item_id": "ks-2a6510492d", + "rationale": "Supplies the underlying theoretical principle of scope." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-15-w2-conditions' contains a virtually identical question and explanation. Combined with the lecture note on scope (ks-2a6510492d), a student can easily deduce the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippet coverage is excellent. There is a direct match in the exam snippets and a clear conceptual explanation in the lecture snippets.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:39:24Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q16", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q16", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "List lambda", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\n\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "list_1[0](1, 2) returns 3 and list_1[1](1, 2) returns 2, so the expression becomes 3 ** 2, which is 9.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "This snippet is an exact duplicate of the target question, providing the identical code context, answer, and a clear breakdown of the lambda evaluation and exponentiation (3 ** 2 = 9)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "Directly answers the question with a full explanation of the logic." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Provides additional context for functions defined with the ** operator (n**2 and n**3), reinforcing that ** means exponentiation." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows general list indexing and printing syntax, which helps a novice understand how items are accessed from a collection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "On its own, this snippet provides the exact question, the math involved, and the final answer." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One of the snippets is the exact question being asked, including the explanation of how lambda parameters are applied and the meaning of the exponentiation operator.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps exist for this specific question because the database contains the identical exam item. However, for a student with zero knowledge, a general summary of 'lambda' syntax would be beneficial for similar but non-identical questions.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:39:42Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q17", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q17", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "List logic", + "question": "You have the following function called main:\n\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat are the outputs of the following lines:\nmain([[], (), []])\nmain([[1], [2, 2], [3, 3, 3]])\nmain([[1], [2], [3]])", + "options": { + "a": "True\nTrue\nTrue", + "b": "True\nFalse\nTrue", + "c": "True\nFalse\nFalse", + "d": "False\nFalse\nTrue" + }, + "correct": "a", + "explanation": "For the first call, each element has length 0, so y becomes [True, True, True] and the comparison is True. In the second and third calls, each element has non-zero length, so y becomes [False, False, False] and the chained equality is also True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Crucially explains how chained equality (x == y == z) is evaluated as (x == y) and (y == z), which is the core logic of the return statement." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Explains chained equality evaluation (x == y == z) and boolean comparisons." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Provides an almost identical structural template: initializing an empty list, looping through an input list, using an if-condition, and appending results." + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Demonstrates the use of the len() function on collections like lists and sets to check for equality." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Clarifies the chained equality logic required to solve the return value." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Shows the list-building pattern (y = [], for loop, append) used in the question." + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Confirms len() is used to count elements in a collection." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets cover the code structure (loop/append), the usage of len(), and most importantly, the non-obvious evaluation of chained equality (x == y == z). A student can map these parts directly to the question logic.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is covered, there is no explicit mention that empty structures like [] or () have a length of 0, nor an explanation of list indexing (y[0]).", + "missing_concepts": [ + "Length of empty collections ([], (), {}) is 0", + "List indexing syntax (y[0], y[1]) for accessing elements" + ], + "proposed_fix": "Add a snippet demonstrating that len([]) is 0 and showing how to access the first element of a list using [0]." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'my_list = [True, False]; len([]); my_list[0] # Returns True'.", + "why_helpful": "This covers two minor gaps: that an empty list has length 0, and that [0] is used to retrieve the first item.", + "why_maybe_unnecessary": "A student might guess that 'empty' means 0 length and that indices start at 0 based on general logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:40:03Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q18", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q18", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "List loop", + "question": "How do you break a list into a list of lists, in which a sub-list consists of 3 values each?\n\nFor example, if the original list x is:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nthen how would you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:i + 3] for i in range(0, 7, 3)]", + "b": "y = [x[0::3] for i, enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of the above works" + }, + "correct": "a", + "explanation": "A slices the list into consecutive groups of three elements. B does not produce the required nested lists.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "This snippet contains the exact question and provides a step-by-step explanation of why Option A is correct, detailing the range generation (0, 3, 6) and the corresponding slice indices." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "Directly answers the question and explains the slicing logic for partitioning a list." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Illustrates the [start:stop:step] slicing syntax, which helps a student understand the 'step' parameter used in the correct answer's range." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Provides additional examples of slicing and list manipulation, reinforcing the concept of extracting sub-parts of a sequence." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "The explanation within this snippet is enough for a student to match the logic of 'range' and 'slicing' to Option A in the question." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-18-w2-conditions' is a direct match for the question and explicitly explains the mechanics of the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide the direct answer. However, they assume the student understands the 'for i in ...' syntax of list comprehensions, even if the mapping to range values is explained.", + "missing_concepts": [ + "List comprehension syntax ([... for ... in ...])" + ], + "proposed_fix": "Add a foundational snippet explaining that list comprehensions create a new list by running an operation for every item in an iterable like range()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Core Concept' snippet for List Comprehensions: Syntax: [expression for item in iterable]. This creates a new list by applying 'expression' to each 'item' in the sequence (like range). Example: [x*2 for x in [1,2,3]] results in [2,4,6].", + "why_helpful": "It bridges the gap for students who see the range/slicing logic explained but don't recognize the structural 'wrapper' of the list comprehension.", + "why_maybe_unnecessary": "The direct explanation in the exam snippet might be enough for a student to simply pick the matching option without fully 'understanding' the loop.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:41:02Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q19", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q19", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-1", + "question": "You have to write a function called main that accepts a dictionary as an input argument. Both the keys and the values of the input are integers.\n\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary, whose keys are smaller than, or equal to, the output key in question.\n\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\n\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "b": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "c": "Both of the above works as intended", + "d": "None of the above work as intended" + }, + "correct": "c", + "explanation": "Option A builds cumulative sums over the sorted keys, and option B directly computes the sum of values whose keys are less than or equal to each output key. Both produce the intended dictionary values.", + "code_context": "Example target behavior:\nmain({5: 1, 2: 5, 4: 2})\n# returns a dictionary equal to {5: 8, 2: 5, 4: 7}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "Shows a function returning a dictionary where values are calculated using aggregate functions like sum(), which is core to both options." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Demonstrates dictionary construction with calculated values (total, min, max)." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Introduces the concept of filtering values when creating a dictionary, relevant to the 'if k <= output_key' logic in Option B." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary creation from a list of strings, helping with the syntax of 'd2[key] = value'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "Syntax for returning dictionaries with calculated values." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Logic for conditional dictionary entry creation." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Context for accessing dictionary values by key for calculations." + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the snippets show dictionary creation and sum(), they lack critical concepts: the sorted() function for keys (Option A), the list comprehension syntax [v for k,v in d.items()] (Option B), and the .items() method itself. A student with zero knowledge would not be able to verify if these specific Python constructs work.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing core syntax for dictionary iteration and sorting.", + "missing_concepts": [ + "sorted() function behavior on dictionary keys", + "List comprehension with filtering syntax", + "dictionary.items() method for key-value iteration", + "Cumulative/running total pattern in a loop" + ], + "proposed_fix": "Add a snippet demonstrating sorted(d.keys()) and a snippet showing a basic list comprehension used to filter and sum data." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'for key in sorted(prices.keys()): ...' and another showing 'sub_total = sum([val for key, val in d.items() if key < 10])'.", + "why_helpful": "This directly maps to the syntax used in Options A and B, allowing a student to recognize the patterns.", + "why_maybe_unnecessary": "If the goal is only to teach dictionary creation, existing snippets are okay, but for this specific logic question, they are inadequate.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:42:23Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q20", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q20", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-2", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) creates key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "This snippet is a verbatim match for the exam question, explicitly stating that d1 (from zip) and d2 (from enumerate) result in the same dictionary {1: 2, 2: 3, 3: 4, 4: 5}, thus making the comparison True." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Provides the direct answer to the exact code scenario and comparison logic described in the question." + }, + { + "item_id": "ks-65c4de2e9d", + "rationale": "Explains the fundamental rule that dictionaries are 'unordered for equality', which is the conceptual basis for why d1 == d2 evaluates to True even if constructed via different iterators." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Offers visual examples of dictionary values and keys being manipulated, helping a novice recognize the 'd[key] = value' pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Since this snippet explicitly contains the solution and the final state of the dictionaries for this specific question, it is sufficient on its own." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes a snippet that is a direct hit for the exact question being asked, providing the answer and the logic in one place.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets provide a 'shortcut' to the answer but don't explain the mechanics of 'zip' and 'enumerate' in a way that allows a student to solve a variation of the question (e.g., if the lists were different).", + "missing_concepts": [ + "The mechanical pairing process of zip(l1, l2).", + "The incremental counter behavior of enumerate(l, start)." + ], + "proposed_fix": "Add a foundational lecture snippet that defines zip and enumerate as pair-generating functions often used for dictionary population." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Iteration Helpers. Snippet: 'zip(l1, l2)' pairs elements by position: (l1[0], l2[0]), (l1[1], l2[1]). 'enumerate(l, start=0)' pairs index with value: (start, l[0]), (start+1, l[1]). These pairs are often used to populate dictionaries with d[key] = value.", + "why_helpful": "It allows a student to derive the result for any list content rather than just matching a specific example.", + "why_maybe_unnecessary": "The verbatim match in the existing exam snippets already solves this specific question perfectly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:05Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q21", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q21", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-3", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\n\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not key-value pairs, so `for key, value in d1:` does not work as intended. The other three options all sum the dictionary values and print the same result.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "This snippet is an exact match for the question logic and provides the specific explanation that iterating directly over a dictionary (for key, value in d1) only yields keys, causing a ValueError during unpacking." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Directly identifies the error in option (a) and explains why it differs from the others." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Provides the fundamental rules for dictionary iteration (.keys(), .values(), .items()), which validates options (b) and (c)." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the exact dictionary structure used in the question and demonstrates extracting values and keys as sequences." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Explains the failure mode of iterating directly without .items()." + }, + { + "item_id": "ks-adb6d9f967", + "rationale": "Explains the correct syntax for the valid options." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions' contains the precise question and explanation, while 'ks-adb6d9f967' covers the underlying mechanics.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are highly effective. A minor gap exists regarding the explicit behavior of the 'sum()' function when applied directly to a dictionary view (option d).", + "missing_concepts": [ + "behavior of sum() on dict_values objects" + ], + "proposed_fix": "Add a snippet demonstrating that 'sum()' works on dictionary views just like it does on lists." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a knowledge snippet: 'Built-in functions and Dictionaries: Functions like sum(), min(), and max() can be applied directly to dictionary views. Example: result = sum(my_dict.values()) correctly totals all values.'", + "why_helpful": "This would explicitly cover option (d) in the question, ensuring a student doesn't have to guess if sum() works on .values().", + "why_maybe_unnecessary": "Option (a) is so clearly identified as an error by the best snippet that the student can identify it by elimination anyway.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:25Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q22", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q22", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-1", + "question": "You have the following string\nx = 'Amsterdam'\n\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method must be called on the string object itself, so `x.count('a')` is the correct form. In 'Amsterdam', there is one lowercase 'a', while the initial uppercase 'A' is not counted.", + "code_context": "x = 'Amsterdam'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "This snippet is a near-identical match to the exam question itself. it explicitly states that .count() is a string method requiring dot notation (x.count('a')) and confirms it is not a standalone function, directly answering the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Directly provides the answer and explains the syntax requirement for the count method." + }, + { + "item_id": "ks-ab66f3bab6", + "rationale": "Provides the general underlying principle: methods are called with dot notation (obj.method()), which explains why 'x.count()' is correct while 'count(x)' is not." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "Identifies the specific method and syntax required for the string 'Amsterdam'." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-22-w2-conditions' contains the exact question and its solution, while the lecture snippet explains the 'why' behind the syntax.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets are excellent for this specific question because it is a direct repeat from a sample exam.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:34Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q23", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q23", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-2", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "For option A, the function returns 6 + 7 + 8 + 9 = 30. For option B, it returns 1 + 4 + 9 + 16 = 30. Both calls therefore produce 30.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "This snippet is a near-perfect match for the target question, providing the exact logic (summing 6+7+8+9 and 1+4+9+16) and the correct answer (C)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Directly contains the logic and solution for the specific math/logic puzzle in the question." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Provides a structural template for passing a lambda as a 'condition' argument and calling it inside a loop, which mirrors the target code." + }, + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "rationale": "Explains the *args syntax (flexible arguments) and demonstrates iterating over them with a loop, which is essential for understanding the function's behavior." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "Provides the direct answer and internal calculation logic." + }, + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "rationale": "Clarifies how *args works as a list-like iterable." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Demonstrates the syntax for defining and calling a lambda passed as a variable." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact exam question from a different year/sample. A student can match the '30' result and the calculation breakdown directly.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is present, the snippets lack a concise 'definition' of lambda syntax (lambda x: ...) for someone with zero programming knowledge.", + "missing_concepts": [ + "Explicit definition of lambda syntax", + "Square operator (**2) clarification" + ], + "proposed_fix": "Add a conceptual snippet for 'Anonymous Functions (Lambda)' that explicitly states 'lambda x: x**2' means 'take x and return x squared'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Lambda and Operators' that explains: 1. lambda x: [expression] creates a small function. 2. ** is the power operator (e.g., 2**3 is 8). 3. *args allows passing any number of values as a list.", + "why_helpful": "It bridges the gap from 'pattern matching the answer' to 'understanding the code' for a true zero-knowledge student.", + "why_maybe_unnecessary": "The student can already find the answer by matching the '30' and the numbers in the intro_python_sample_final snippet.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:44:53Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + }, + { + "evaluation_id": "round1:trial-final-exam-solutions-introduction-to-python-3077951-q24", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q24", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-3", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\n\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C imports the module under the name `constants`, but then tries to access `math.pi`, where `math` is not defined. The other options all reference pi correctly and would print the correct area.", + "code_context": "Area formula: πr²" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This snippet is a direct match for the question logic. It explicitly explains that 'import math as constants' requires using 'constants.pi' and that 'math.pi' becomes unavailable, which is the exact reason option C is incorrect." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "Directly addresses the import aliasing ('import as') mechanic and why the original name is no longer defined." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains that 'print' is a function used to output arguments to the screen, which helps a novice understand what the code intends to do." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "While not directly about imports, it demonstrates the use of the '**2' operator for squaring numbers, confirming the math formula syntax." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "Provides the specific rule required to identify the incorrect option." + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-24-w2-conditions' contains a verbatim explanation of the 'import as' concept applied to the math module and the circle area problem.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide a perfect match for the specific technical hurdle (module aliasing) and the general syntax (print, power operator).", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-23T19:45:32Z", + "model": "gemini-3-flash-preview", + "candidate_item_count": 18 + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/final-exam-solutions-for-python-programming-62oop21.json b/data/vision_exam_pipeline/work_packets/extractions/final-exam-solutions-for-python-programming-62oop21.json new file mode 100644 index 0000000..0852a79 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/final-exam-solutions-for-python-programming-62oop21.json @@ -0,0 +1,174 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "title": "2022 Final Exam", + "expected_questions": 24, + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-solutions-for-python-programming-62oop21.pdf", + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-02.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-03.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-04.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-05.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-06.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-07.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-08.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-09.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-10.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-11.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-12.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-13.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-14.png", + "tmp/exam_coverage_audit/pages/final-exam-solutions-for-python-programming-62oop21/page-15.png" + ], + "captured_question_numbers": [ + 1, + 2, + 3, + 4, + 5 + ], + "pending_question_numbers": [ + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24 + ], + "blocked_questions": [ + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q06", + "number": 6, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q07", + "number": 7, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q08", + "number": 8, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q09", + "number": 9, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q10", + "number": 10, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q11", + "number": 11, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q12", + "number": 12, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q13", + "number": 13, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q14", + "number": 14, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q15", + "number": 15, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q16", + "number": 16, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q17", + "number": 17, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q18", + "number": 18, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q19", + "number": 19, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q20", + "number": 20, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q21", + "number": 21, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q22", + "number": 22, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q23", + "number": 23, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-solutions-for-python-programming-62oop21-q24", + "number": 24, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + } + ], + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes." + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/final-exam-study-guide-trial-python-basics-2023.json b/data/vision_exam_pipeline/work_packets/extractions/final-exam-study-guide-trial-python-basics-2023.json new file mode 100644 index 0000000..23a59e3 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/final-exam-study-guide-trial-python-basics-2023.json @@ -0,0 +1,170 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "title": "2023 Trial Final Study Guide", + "expected_questions": 24, + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/final-exam-study-guide-trial-python-basics-2023.pdf", + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-01.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-02.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-03.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-04.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-05.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-06.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-07.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-08.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-09.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-10.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-11.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-12.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-13.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-14.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-15.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-16.png", + "tmp/exam_coverage_audit/pages/final-exam-study-guide-trial-python-basics-2023/page-17.png" + ], + "captured_question_numbers": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "pending_question_numbers": [ + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24 + ], + "blocked_questions": [ + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q07", + "number": 7, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q08", + "number": 8, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q09", + "number": 9, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q10", + "number": 10, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q11", + "number": 11, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q12", + "number": 12, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q13", + "number": 13, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q14", + "number": 14, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q15", + "number": 15, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q16", + "number": 16, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q17", + "number": 17, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q18", + "number": 18, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q19", + "number": 19, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q20", + "number": 20, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q21", + "number": 21, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q22", + "number": 22, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q23", + "number": 23, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "final-exam-study-guide-trial-python-basics-2023-q24", + "number": 24, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + } + ], + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes." + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/index.json b/data/vision_exam_pipeline/work_packets/extractions/index.json new file mode 100644 index 0000000..bded82e --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/index.json @@ -0,0 +1,57 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "question_bank_path": "data/vision_exam_pipeline/exam_question_bank.json", + "packet_count": 7, + "packets": [ + { + "exam_id": "sample-final-plus-answers", + "expected_questions": 24, + "captured_questions": 24, + "pending_questions": 0, + "packet_path": "data/vision_exam_pipeline/work_packets/extractions/sample-final-plus-answers.json" + }, + { + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "expected_questions": 24, + "captured_questions": 5, + "pending_questions": 19, + "packet_path": "data/vision_exam_pipeline/work_packets/extractions/final-exam-solutions-for-python-programming-62oop21.json" + }, + { + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "expected_questions": 24, + "captured_questions": 6, + "pending_questions": 18, + "packet_path": "data/vision_exam_pipeline/work_packets/extractions/final-exam-study-guide-trial-python-basics-2023.json" + }, + { + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "expected_questions": 24, + "captured_questions": 7, + "pending_questions": 17, + "packet_path": "data/vision_exam_pipeline/work_packets/extractions/introduction-to-python-trial-final-exam-solutions-py22.json" + }, + { + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "expected_questions": 24, + "captured_questions": 6, + "pending_questions": 18, + "packet_path": "data/vision_exam_pipeline/work_packets/extractions/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json" + }, + { + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "expected_questions": 24, + "captured_questions": 7, + "pending_questions": 17, + "packet_path": "data/vision_exam_pipeline/work_packets/extractions/resit-solutions-for-introduction-to-python-35761538.json" + }, + { + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "expected_questions": 24, + "captured_questions": 6, + "pending_questions": 18, + "packet_path": "data/vision_exam_pipeline/work_packets/extractions/trial-final-exam-solutions-introduction-to-python-3077951.json" + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/introduction-to-python-trial-final-exam-solutions-py22.json b/data/vision_exam_pipeline/work_packets/extractions/introduction-to-python-trial-final-exam-solutions-py22.json new file mode 100644 index 0000000..1f97a63 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/introduction-to-python-trial-final-exam-solutions-py22.json @@ -0,0 +1,164 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "title": "2024 Trial Final", + "expected_questions": 24, + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/introduction-to-python-trial-final-exam-solutions-py22.pdf", + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-01.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-02.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-03.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-04.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-05.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-06.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-07.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-08.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-09.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-10.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-11.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-12.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-13.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-14.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-15.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-16.png", + "tmp/exam_coverage_audit/pages/introduction-to-python-trial-final-exam-solutions-py22/page-17.png" + ], + "captured_question_numbers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "pending_question_numbers": [ + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24 + ], + "blocked_questions": [ + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q08", + "number": 8, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q09", + "number": 9, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q10", + "number": 10, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q11", + "number": 11, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q12", + "number": 12, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q13", + "number": 13, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q14", + "number": 14, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q15", + "number": 15, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q16", + "number": 16, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q17", + "number": 17, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q18", + "number": 18, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q19", + "number": 19, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q20", + "number": 20, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q21", + "number": 21, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q22", + "number": 22, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q23", + "number": 23, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q24", + "number": 24, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + } + ], + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes." + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json b/data/vision_exam_pipeline/work_packets/extractions/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json new file mode 100644 index 0000000..142f195 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json @@ -0,0 +1,170 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "title": "2023 Resit Exam Guidelines", + "expected_questions": 24, + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.pdf", + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-01.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-02.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-03.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-04.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-05.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-06.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-07.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-08.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-09.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-10.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-11.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-12.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-13.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-14.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-15.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-16.png", + "tmp/exam_coverage_audit/pages/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023/page-17.png" + ], + "captured_question_numbers": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "pending_question_numbers": [ + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24 + ], + "blocked_questions": [ + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "number": 7, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "number": 8, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "number": 9, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "number": 10, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "number": 11, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "number": 12, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "number": 13, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "number": 14, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "number": 15, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "number": 16, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "number": 17, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "number": 18, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "number": 19, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "number": 20, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "number": 21, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "number": 22, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "number": 23, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "number": 24, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + } + ], + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes." + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/resit-solutions-for-introduction-to-python-35761538.json b/data/vision_exam_pipeline/work_packets/extractions/resit-solutions-for-introduction-to-python-35761538.json new file mode 100644 index 0000000..dedb945 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/resit-solutions-for-introduction-to-python-35761538.json @@ -0,0 +1,164 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "title": "2023 Resit Solutions", + "expected_questions": 24, + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/resit-solutions-for-introduction-to-python-35761538.pdf", + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-01.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-02.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-03.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-04.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-05.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-06.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-07.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-08.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-09.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-10.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-11.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-12.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-13.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-14.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-15.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-16.png", + "tmp/exam_coverage_audit/pages/resit-solutions-for-introduction-to-python-35761538/page-17.png" + ], + "captured_question_numbers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7 + ], + "pending_question_numbers": [ + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24 + ], + "blocked_questions": [ + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q08", + "number": 8, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q09", + "number": 9, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q10", + "number": 10, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q11", + "number": 11, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q12", + "number": 12, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q13", + "number": 13, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q14", + "number": 14, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q15", + "number": 15, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q16", + "number": 16, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q17", + "number": 17, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q18", + "number": 18, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q19", + "number": 19, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q20", + "number": 20, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q21", + "number": 21, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q22", + "number": 22, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q23", + "number": 23, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "resit-solutions-for-introduction-to-python-35761538-q24", + "number": 24, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + } + ], + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes." + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/sample-final-plus-answers.json b/data/vision_exam_pipeline/work_packets/extractions/sample-final-plus-answers.json new file mode 100644 index 0000000..848e154 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/sample-final-plus-answers.json @@ -0,0 +1,74 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "exam_id": "sample-final-plus-answers", + "title": "2025 Sample Final Plus Answers", + "expected_questions": 24, + "pdf_path": "../course_files_after_midterm/Sample Final plus answers.pdf", + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-01.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-02.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-03.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-04.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-05.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-06.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-07.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-08.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-09.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-10.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-11.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-12.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-13.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-14.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-15.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-16.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-17.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-18.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-19.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-20.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-21.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-22.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-23.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-24.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-25.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-26.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-27.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-28.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-29.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-30.png", + "tmp/exam_coverage_audit/pages/sample-final-plus-answers/page-31.png" + ], + "captured_question_numbers": [ + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24 + ], + "pending_question_numbers": [], + "blocked_questions": [], + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes." + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/extractions/trial-final-exam-solutions-introduction-to-python-3077951.json b/data/vision_exam_pipeline/work_packets/extractions/trial-final-exam-solutions-introduction-to-python-3077951.json new file mode 100644 index 0000000..43bebc3 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/extractions/trial-final-exam-solutions-introduction-to-python-3077951.json @@ -0,0 +1,166 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-23T16:24:36Z", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "title": "Trial Final Later-Course Focus", + "expected_questions": 24, + "pdf_path": "../course_files_after_midterm/practice_exams_previous_years/trial-final-exam-solutions-introduction-to-python-3077951.pdf", + "page_image_paths": [ + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-01.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-02.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-03.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-04.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-05.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-06.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-07.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-08.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-09.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-10.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-11.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-12.png", + "tmp/exam_coverage_audit/pages/trial-final-exam-solutions-introduction-to-python-3077951/page-13.png" + ], + "captured_question_numbers": [ + 1, + 2, + 3, + 4, + 5, + 6 + ], + "pending_question_numbers": [ + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 18, + 19, + 20, + 21, + 22, + 23, + 24 + ], + "blocked_questions": [ + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q07", + "number": 7, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q08", + "number": 8, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q09", + "number": 9, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q10", + "number": 10, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q11", + "number": 11, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q12", + "number": 12, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q13", + "number": 13, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q14", + "number": 14, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q15", + "number": 15, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q16", + "number": 16, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q17", + "number": 17, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q18", + "number": 18, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q19", + "number": 19, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q20", + "number": 20, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q21", + "number": 21, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q22", + "number": 22, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q23", + "number": 23, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + }, + { + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q24", + "number": 24, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model." + } + ], + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes." + ] +} \ No newline at end of file diff --git a/docs/TESTING.md b/docs/TESTING.md index 9b85a5a..6ee1a96 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -52,6 +52,55 @@ Notes: - It mirrors the current UI's selectable-item rules, so `ai_summary` is excluded while key-point details and both source buckets are included. - It is intended for manual or agent-led vision review of the rendered PNG pages, not text-layer parsing or OCR. +## Vision-First Exam Curation + +The next exam-curation phase treats rendered page images as the review source of truth and keeps extracted question/ranking artifacts as separate JSON products under `data/`. + +Pipeline contract: + +1. Render each target exam PDF to page PNGs. +2. Have agents review the PNGs with vision only, with no `pdftotext`, OCR, or other text-layer extraction. +3. Store the reviewed questions in a persistent question bank. +4. Score each question against selectable snippets, key points, and common exam questions. +5. Synthesize edit/addition suggestions and ranking analytics for human review before any UI or preset changes. + +Derived artifact families now live under `data/vision_exam_pipeline/`: + +- `data/vision_exam_pipeline/page_manifest.json` +- `data/vision_exam_pipeline/exam_question_bank.json` +- `data/vision_exam_pipeline/exam_question_bank_completeness.json` +- `data/vision_exam_pipeline/selectable_items_snapshot.json` +- `data/vision_exam_pipeline/evaluations/.json` +- `data/vision_exam_pipeline/synthesis/.json` +- `data/vision_exam_pipeline/analytics/.json` +- `data/vision_exam_pipeline/analytics/.md` +- `data/vision_exam_pipeline/review_packets/.json` +- `data/vision_exam_pipeline/review_packets/.md` +- `data/vision_exam_pipeline/work_packets/extractions/*.json` +- `data/vision_exam_pipeline/work_packets/evaluations//*.json` + +The existing render packet remains the practical starting point for this workflow: + +- `tmp/exam_coverage_audit/manifest.json` +- `tmp/exam_coverage_audit/selectable_items.json` +- `tmp/exam_coverage_audit/pages//page-XX.png` + +See [RM-009 Vision-First Exam Curation Pipeline](specs/RM-009-vision-first-exam-curation-pipeline.md) for the implementation contract and review checkpoints. + +Current entrypoint: + +```bash +python3 scripts/vision_exam_pipeline.py prepare-pages +python3 scripts/vision_exam_pipeline.py seed-question-bank +python3 scripts/vision_exam_pipeline.py audit-completeness +python3 scripts/vision_exam_pipeline.py dispatch-extraction +python3 scripts/vision_exam_pipeline.py dispatch-evaluations --round round1 --findings tmp/exam_coverage_audit/seed_exact_matches.json +python3 scripts/vision_exam_pipeline.py synthesize-suggestions --round round1 +python3 scripts/vision_exam_pipeline.py generate-ranking-analytics --round round1 +python3 scripts/vision_exam_pipeline.py generate-review-packet --round round1 +python3 scripts/vision_exam_pipeline.py validate --evaluation-round round1 +``` + ## Maintenance Audit ```bash diff --git a/docs/data/DATASET_INFO.md b/docs/data/DATASET_INFO.md index 6ba8a5a..910701b 100644 --- a/docs/data/DATASET_INFO.md +++ b/docs/data/DATASET_INFO.md @@ -14,6 +14,47 @@ Related generated audit artifact: This report records coverage for homework exercises and assessment questions against the current `topic_cards.json` output. +## Exam Curation Data + +`data/study_db.json` remains the canonical course-content database, but the vision-first exam-curation workflow keeps its review products separate from the main study DB. + +Vision-only capture rule: + +- exam pages are rendered to PNGs and reviewed by agents with vision +- exam question capture should not rely on `pdftotext`, OCR, or other deterministic text-layer extraction +- legacy imports in `data/import_payloads/post_midterm_assessments/` and `data/import_payloads/post_midterm_agent/` are treated as seed material, not final ground truth, until they are superseded by reviewed vision records + +Derived exam artifacts live under `data/vision_exam_pipeline/` as separate JSON products: + +- `page_manifest.json` + - persistent manifest of target exams and rendered/reused page PNG paths +- `exam_question_bank.json` + - canonical per-exam reviewed question bank with alias metadata, provenance, and blocked question slots +- `exam_question_bank_completeness.json` + - completeness report that fails open questions into explicit blocked slots +- `selectable_items_snapshot.json` + - stable snapshot of the current selectable snippet universe used for review rounds +- `evaluations/.json` + - per-question snippet evaluation records, answerability notes, and suggested changes +- `synthesis/.json` + - grouped edit/addition suggestions with pros, cons, and human-review status +- `analytics/.json` and `analytics/.md` + - week-level snippet-usage distributions and ranking-prep summaries +- `review_packets/.json` and `review_packets/.md` + - human-facing review packet that clusters round findings into decision-ready themes and top-snippet summaries +- `work_packets/extractions/*.json` + - per-exam vision-review capture packets +- `work_packets/evaluations//*.json` + - per-exam question-to-snippet review packets + +The current render-and-review packet used by the audit workflow is still the fastest way to bootstrap those artifacts: + +- `tmp/exam_coverage_audit/manifest.json` +- `tmp/exam_coverage_audit/selectable_items.json` +- `tmp/exam_coverage_audit/pages//page-XX.png` + +See [RM-009 Vision-First Exam Curation Pipeline](../specs/RM-009-vision-first-exam-curation-pipeline.md) for the workflow contract. + ## Raw Source Materials Course/source files are organized under `materials/`: diff --git a/docs/specs/RM-009-vision-first-exam-curation-pipeline.md b/docs/specs/RM-009-vision-first-exam-curation-pipeline.md new file mode 100644 index 0000000..c06e365 --- /dev/null +++ b/docs/specs/RM-009-vision-first-exam-curation-pipeline.md @@ -0,0 +1,72 @@ +# Spec: RM-009 Vision-First Exam Curation Pipeline + +## Metadata + +- ID: `RM-009` +- Status: `planned` +- Priority: `High` +- Owner: `codex/human` +- Last Updated: `2026-03-23` + +## Problem + +The repo already contains exam imports and audit packets, but the exam data is still a mix of partial imports, legacy provenance, and text/OCR-derived material. That makes it hard to guarantee that every past/mock exam question is captured once, reviewed consistently, and mapped to the most useful snippet evidence for student-facing curation. + +## Goals + +- Build a vision-only exam capture workflow that treats rendered page images as the source of truth for question review. +- Store a persistent canonical question bank for each unique exam, including duplicate/alias metadata and explicit completeness status. +- Add question-to-snippet evaluation artifacts that record the best snippets, top 3 snippets, minimal sufficient snippet sets, and gap notes. +- Produce synthesis and ranking outputs that can drive later snippet reclassification, presets, and week-level leaderboards. + +## Non-Goals + +- Rewriting the Topic Explorer UI in this phase. +- Implementing leaderboard or preset pages before the ranking logic is agreed. +- Using `pdftotext`, OCR, or any other deterministic text-layer extraction for exam question capture. + +## Proposed Solution + +Keep `data/study_db.json` as the canonical course-content database, but add separate derived JSON artifacts under `data/vision_exam_pipeline/` for the exam workflow: + +- a question bank for reviewed exam questions and provenance +- a question-evaluation file for snippet scoring and answerability notes +- a synthesis file for suggested edits/additions with pros/cons +- a ranking summary for weekly highest-value snippet analysis + +Use the existing render packet pattern from `scripts/exam_coverage_audit.py` as the bootstrap for page PNG generation, then have agents review only the PNGs. The orchestrator should be resumable and idempotent so page rendering, question capture, evaluation, synthesis, and analytics can be run in separate passes. + +## Implementation Plan + +1. Add a pipeline entrypoint (`scripts/vision_exam_pipeline.py`) that can prepare page renders, audit completeness, record reviewed questions, evaluate snippet evidence, synthesize edits, and generate ranking analytics. +2. Define stable JSON contracts for the question bank, evaluations, synthesis, and ranking outputs. +3. Seed the new artifacts from the current audit packet and legacy imports, but mark legacy records as provisional until they are superseded by vision-reviewed records. +4. Document the workflow in the testing and dataset references so future curation rounds follow the same capture and review policy. + +## Risks and Mitigations + +- Risk: Duplicate PDFs could create duplicate canonical entries. +- Mitigation: Keep one canonical exam record per unique exam and store duplicate copies as aliases/audit evidence only. +- Risk: Mixing OCR-derived and vision-derived records could blur provenance. +- Mitigation: Preserve explicit provenance fields and treat the vision-reviewed records as the authoritative layer. +- Risk: Ranking logic may be premature before the evaluation round is complete. +- Mitigation: Keep ranking outputs separate from UI implementation and gate step 8 on the human review round. + +## Test Plan + +- Validate every derived JSON artifact against a schema. +- Check that each unique target exam reaches the expected question count. +- Verify the duplicate 2022 final does not produce a second canonical exam bank entry. +- Confirm every snippet reference points at a currently selectable item. +- Re-run the pipeline from a partial state to confirm resume/idempotency. + +## Rollout and Validation + +- Start with the seven unique exam sources already covered by the audit packet. +- Reuse the existing rendered PNG packet when it matches the current source PDFs. +- Review the question bank and evaluation summaries before implementing any snippet reclassification or UI changes. + +## Open Questions + +- Which exact JSON filenames should be treated as the long-term canonical review artifacts if the pipeline expands further? +- Should page PNGs remain temporary regeneration artifacts, or should some be stored in a persistent local cache for repeated vision passes? diff --git a/pipelines/vision_exam_pipeline.py b/pipelines/vision_exam_pipeline.py new file mode 100644 index 0000000..41b68ec --- /dev/null +++ b/pipelines/vision_exam_pipeline.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +from pipelines.vision_exam_pipeline_bank import ( + build_completeness_report, + merge_review_drop, + prepare_page_manifest, + seed_question_bank, + write_completeness_report, + write_extraction_packets, +) +from pipelines.vision_exam_pipeline_gemini import ( + auto_capture_missing_questions, + auto_evaluate_questions, +) +from pipelines.vision_exam_pipeline_packet import ( + build_review_packet, + write_review_packet, +) +from pipelines.vision_exam_pipeline_review import ( + build_evaluation_scaffold, + build_ranking_analytics, + build_selectable_items_snapshot, + synthesize_suggestions, + validate_all, + validate_evaluation_payload, + write_evaluation_scaffold, + write_ranking_analytics, +) +from pipelines.vision_exam_pipeline_shared import ( + ANALYTICS_DIR, + COMPLETENESS_FILE, + DATA_ROOT, + EVALUATIONS_DIR, + LEGACY_ASSESSMENT_DIR, + PAGE_MANIFEST_FILE, + QUESTION_BANK_FILE, + REVIEW_DROP_DIR, + REVIEW_PACKET_DIR, + SELECTABLE_ITEMS_FILE, + SYNTHESIS_DIR, + TMP_ROOT, + WORK_PACKET_DIR, + duplicate_exam_aliases, + unique_exam_sources, + validate_question_bank_payload, +) + +__all__ = [ + "ANALYTICS_DIR", + "COMPLETENESS_FILE", + "DATA_ROOT", + "EVALUATIONS_DIR", + "LEGACY_ASSESSMENT_DIR", + "PAGE_MANIFEST_FILE", + "QUESTION_BANK_FILE", + "REVIEW_DROP_DIR", + "REVIEW_PACKET_DIR", + "SELECTABLE_ITEMS_FILE", + "SYNTHESIS_DIR", + "TMP_ROOT", + "WORK_PACKET_DIR", + "auto_capture_missing_questions", + "auto_evaluate_questions", + "build_completeness_report", + "build_evaluation_scaffold", + "build_ranking_analytics", + "build_review_packet", + "build_selectable_items_snapshot", + "duplicate_exam_aliases", + "merge_review_drop", + "prepare_page_manifest", + "seed_question_bank", + "synthesize_suggestions", + "unique_exam_sources", + "validate_all", + "validate_evaluation_payload", + "validate_question_bank_payload", + "write_completeness_report", + "write_evaluation_scaffold", + "write_extraction_packets", + "write_ranking_analytics", + "write_review_packet", +] diff --git a/pipelines/vision_exam_pipeline_bank.py b/pipelines/vision_exam_pipeline_bank.py new file mode 100644 index 0000000..e6e77f1 --- /dev/null +++ b/pipelines/vision_exam_pipeline_bank.py @@ -0,0 +1,466 @@ +from __future__ import annotations + +from copy import deepcopy +from pathlib import Path +from typing import Any + +from pipelines.vision_exam_pipeline_shared import ( + COMPLETENESS_FILE, + LEGACY_ASSESSMENT_DIR, + PAGE_MANIFEST_FILE, + PAGE_MANIFEST_SCHEMA, + QUESTION_BANK_FILE, + QUESTION_BANK_SCHEMA, + TMP_ROOT, + WORK_PACKET_DIR, + _default_blocked_question, + _existing_page_paths, + _normalize_question_options, + _question_id, + _read_json, + _safe_dict, + _safe_list, + _safe_str, + _slugify, + _write_json, + duplicate_exam_aliases, + load_study_db, + portable_path, + render_exam_pages, + timestamp_utc, + unique_exam_sources, +) + + +def prepare_page_manifest( + *, + tmp_dir: Path = TMP_ROOT, + manifest_path: Path = PAGE_MANIFEST_FILE, + dpi: int = 160, + overwrite: bool = False, +) -> dict[str, Any]: + page_root = tmp_dir / "pages" + exams_payload = [] + for exam in unique_exam_sources(): + existing_pages = [] if overwrite else _existing_page_paths(exam["exam_id"]) + if existing_pages: + pages = existing_pages + render_status = "reused_existing_pages" + else: + pages = render_exam_pages(exam, page_root, dpi=dpi, overwrite=overwrite) + render_status = "rendered_now" + exams_payload.append( + { + "exam_id": exam["exam_id"], + "title": exam["title"], + "group": exam["group"], + "pdf_path": portable_path(Path(exam["pdf_path"])), + "expected_questions": int(exam["expected_questions"]), + "page_count": len(pages), + "page_image_paths": [portable_path(path) for path in pages], + "render_status": render_status, + } + ) + manifest = { + "schema_version": PAGE_MANIFEST_SCHEMA, + "generated_at": timestamp_utc(), + "policy": { + "vision_only_question_capture": True, + "text_layer_extraction_forbidden": True, + "ocr_forbidden": True, + "page_rendering_allowed": True, + }, + "duplicate_aliases": duplicate_exam_aliases(), + "exams": exams_payload, + } + _write_json(manifest_path, manifest) + return manifest + + +def _legacy_payload_index(payload_dir: Path = LEGACY_ASSESSMENT_DIR) -> dict[str, dict[str, Any]]: + index: dict[str, dict[str, Any]] = {} + for path in sorted(payload_dir.glob("*.json")): + payload = _read_json(path) + if not isinstance(payload, dict): + continue + payload["_payload_path"] = portable_path(path) + keys = { + _slugify(path.stem), + _slugify(Path(_safe_str(payload.get("source"))).stem), + _slugify(payload.get("exam_label")), + } + for key in keys: + if key and key not in index: + index[key] = payload + return index + + +def _study_db_assessment_index() -> dict[str, dict[str, Any]]: + db = load_study_db() + exams = _safe_list(_safe_dict(db.get("assessments")).get("exams")) + index: dict[str, dict[str, Any]] = {} + for exam in exams: + if not isinstance(exam, dict): + continue + keys = { + _slugify(exam.get("exam_label")), + _slugify(Path(_safe_str(exam.get("source"))).stem), + } + for key in keys: + if key and key not in index: + index[key] = exam + return index + + +def _seed_question_record(exam_id: str, question: dict[str, Any], *, payload_path: str) -> dict[str, Any]: + number = int(question["number"]) + return { + "question_id": _question_id(exam_id, number), + "number": number, + "topic": _safe_str(question.get("topic")), + "question": _safe_str(question.get("question")), + "options": _normalize_question_options(question.get("options")), + "correct": _safe_str(question.get("correct")), + "explanation": _safe_str(question.get("explanation")), + "code_context": _safe_str(question.get("code_context")), + "provenance": { + "origin": "legacy_assessment_payload", + "origin_path": payload_path, + "capture_method": "legacy_text_or_ocr_seed", + "review_status": "seeded_legacy_needs_vision_review", + "review_pass": 0, + "human_confirmed": False, + "page_refs": [], + "notes": [], + }, + } + + +def _merge_questions( + *, + exam_id: str, + expected_questions: int, + existing_exam: dict[str, Any], + legacy_payload: dict[str, Any] | None, +) -> tuple[list[dict[str, Any]], list[dict[str, Any]]]: + existing_questions = { + int(question["number"]): deepcopy(question) + for question in _safe_list(existing_exam.get("questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + existing_blocked = { + int(question["number"]): deepcopy(question) + for question in _safe_list(existing_exam.get("blocked_questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + legacy_questions: dict[int, dict[str, Any]] = {} + if legacy_payload: + payload_path = _safe_str(legacy_payload.get("_payload_path")) + for question in _safe_list(legacy_payload.get("questions")): + if isinstance(question, dict) and str(question.get("number", "")).isdigit(): + number = int(question["number"]) + legacy_questions.setdefault(number, _seed_question_record(exam_id, question, payload_path=payload_path)) + + merged_questions = [] + blocked_questions = [] + for number in range(1, expected_questions + 1): + if number in existing_questions: + merged_questions.append(existing_questions[number]) + elif number in legacy_questions: + merged_questions.append(legacy_questions[number]) + else: + blocked_questions.append(existing_blocked.get(number) or _default_blocked_question(exam_id, number)) + return sorted(merged_questions, key=lambda item: int(item["number"])), sorted(blocked_questions, key=lambda item: int(item["number"])) + + +def _page_manifest_index(manifest: dict[str, Any]) -> dict[str, dict[str, Any]]: + return { + _safe_str(exam.get("exam_id")): exam + for exam in _safe_list(manifest.get("exams")) + if isinstance(exam, dict) + } + + +def _review_tracking(questions: list[dict[str, Any]], blocked_questions: list[dict[str, Any]]) -> dict[str, int]: + confirmed = 0 + seeded = 0 + for question in questions: + provenance = _safe_dict(question.get("provenance")) + if bool(provenance.get("human_confirmed")): + confirmed += 1 + if _safe_str(provenance.get("origin")) == "legacy_assessment_payload": + seeded += 1 + return { + "present_questions": len(questions), + "blocked_questions": len(blocked_questions), + "human_confirmed_questions": confirmed, + "legacy_seeded_questions": seeded, + "pending_vision_questions": len(blocked_questions), + } + + +def _exam_status(tracking: dict[str, int]) -> str: + if tracking["blocked_questions"] == 0 and tracking["present_questions"] == tracking["human_confirmed_questions"]: + return "complete" + if tracking["present_questions"] > 0: + return "partial" + return "not_started" + + +def seed_question_bank( + *, + question_bank_path: Path = QUESTION_BANK_FILE, + page_manifest_path: Path = PAGE_MANIFEST_FILE, +) -> dict[str, Any]: + page_manifest = _read_json(page_manifest_path) if page_manifest_path.exists() else prepare_page_manifest() + page_index = _page_manifest_index(page_manifest) + legacy_index = _legacy_payload_index() + study_db_index = _study_db_assessment_index() + existing = _read_json(question_bank_path) if question_bank_path.exists() else {} + existing_exams = { + _safe_str(exam.get("exam_id")): exam + for exam in _safe_list(_safe_dict(existing).get("exams")) + if isinstance(exam, dict) + } + + exams_payload = [] + for exam in unique_exam_sources(): + exam_id = exam["exam_id"] + page_entry = page_index.get(exam_id, {}) + lookup_keys = {_slugify(exam_id), _slugify(Path(str(exam["pdf_path"])).stem), _slugify(exam["title"])} + legacy_payload = next((legacy_index[key] for key in lookup_keys if key in legacy_index), None) + study_db_exam = next((study_db_index[key] for key in lookup_keys if key in study_db_index), None) + questions, blocked_questions = _merge_questions( + exam_id=exam_id, + expected_questions=int(exam["expected_questions"]), + existing_exam=deepcopy(existing_exams.get(exam_id, {})), + legacy_payload=legacy_payload, + ) + tracking = _review_tracking(questions, blocked_questions) + exams_payload.append( + { + "exam_id": exam_id, + "title": exam["title"], + "group": exam["group"], + "pdf_path": portable_path(Path(exam["pdf_path"])), + "expected_questions": int(exam["expected_questions"]), + "page_image_paths": _safe_list(page_entry.get("page_image_paths")), + "page_count": int(page_entry.get("page_count") or 0), + "duplicate_aliases": [alias for alias in duplicate_exam_aliases() if _safe_str(alias.get("duplicate_of")) == exam_id], + "seed_sources": { + "legacy_assessment_payload_path": _safe_str(_safe_dict(legacy_payload).get("_payload_path")), + "study_db_exam_label": _safe_str(_safe_dict(study_db_exam).get("exam_label")), + "study_db_exam_source": _safe_str(_safe_dict(study_db_exam).get("source")), + "legacy_provenance_warning": "Existing imported questions may originate from pdftotext/OCR-era extraction and require vision review.", + }, + "review_tracking": tracking, + "extraction_status": _exam_status(tracking), + "questions": questions, + "blocked_questions": blocked_questions, + } + ) + + payload = { + "schema_version": QUESTION_BANK_SCHEMA, + "generated_at": timestamp_utc(), + "policy": { + "vision_only_question_capture": True, + "text_layer_extraction_forbidden": True, + "ocr_forbidden": True, + "human_review_checkpoint_required": True, + }, + "canonical_exam_count": len(exams_payload), + "duplicate_aliases": duplicate_exam_aliases(), + "page_manifest_path": portable_path(page_manifest_path), + "exams": exams_payload, + } + _write_json(question_bank_path, payload) + return payload + + +def build_completeness_report(question_bank: dict[str, Any]) -> dict[str, Any]: + exams_report = [] + incomplete = [] + reviewed_total = 0 + expected_total = 0 + for exam in _safe_list(question_bank.get("exams")): + if not isinstance(exam, dict): + continue + expected = int(exam.get("expected_questions") or 0) + question_numbers = { + int(question["number"]) + for question in _safe_list(exam.get("questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + blocked_numbers = { + int(question["number"]) + for question in _safe_list(exam.get("blocked_questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + missing_without_reason = [number for number in range(1, expected + 1) if number not in question_numbers | blocked_numbers] + confirmed = sum( + 1 + for question in _safe_list(exam.get("questions")) + if isinstance(question, dict) and bool(_safe_dict(question.get("provenance")).get("human_confirmed")) + ) + # Completeness tracks whether every expected question slot is covered. + # Human confirmation remains a separate provenance signal. + status = "complete" if not blocked_numbers and not missing_without_reason else "incomplete" + row = { + "exam_id": _safe_str(exam.get("exam_id")), + "title": _safe_str(exam.get("title")), + "expected_questions": expected, + "present_questions": len(question_numbers), + "blocked_questions": len(blocked_numbers), + "human_confirmed_questions": confirmed, + "missing_without_reason": missing_without_reason, + "status": status, + } + exams_report.append(row) + reviewed_total += len(question_numbers) + expected_total += expected + if status != "complete": + incomplete.append(row["exam_id"]) + return { + "schema_version": QUESTION_BANK_SCHEMA, + "generated_at": timestamp_utc(), + "question_bank_schema_version": _safe_str(question_bank.get("schema_version")), + "overall_status": "complete" if not incomplete else "incomplete", + "summary": { + "canonical_exam_count": len(exams_report), + "complete_exam_count": sum(1 for row in exams_report if row["status"] == "complete"), + "incomplete_exam_count": len(incomplete), + "reviewed_question_count": reviewed_total, + "expected_question_count": expected_total, + }, + "exams": exams_report, + } + + +def write_completeness_report( + *, + question_bank_path: Path = QUESTION_BANK_FILE, + report_path: Path = COMPLETENESS_FILE, +) -> dict[str, Any]: + report = build_completeness_report(_read_json(question_bank_path)) + _write_json(report_path, report) + return report + + +def write_extraction_packets( + *, + question_bank_path: Path = QUESTION_BANK_FILE, + output_dir: Path | None = None, +) -> dict[str, Any]: + question_bank = _read_json(question_bank_path) + packet_dir = output_dir or (WORK_PACKET_DIR / "extractions") + packets = [] + for exam in _safe_list(question_bank.get("exams")): + if not isinstance(exam, dict): + continue + questions = [question for question in _safe_list(exam.get("questions")) if isinstance(question, dict)] + blocked = [question for question in _safe_list(exam.get("blocked_questions")) if isinstance(question, dict)] + packet = { + "schema_version": QUESTION_BANK_SCHEMA, + "generated_at": timestamp_utc(), + "exam_id": _safe_str(exam.get("exam_id")), + "title": _safe_str(exam.get("title")), + "expected_questions": int(exam.get("expected_questions") or 0), + "pdf_path": _safe_str(exam.get("pdf_path")), + "page_image_paths": _safe_list(exam.get("page_image_paths")), + "captured_question_numbers": [int(question["number"]) for question in questions if str(question.get("number", "")).isdigit()], + "pending_question_numbers": [int(question["number"]) for question in blocked if str(question.get("number", "")).isdigit()], + "blocked_questions": blocked, + "instructions": [ + "Use only the rendered PNG page images for question capture.", + "Do not use OCR, pdftotext, or any deterministic text extraction.", + "For each pending question, record the full question text, answer options, correct answer, and explanation with provenance notes.", + ], + } + packets.append(packet) + _write_json(packet_dir / f"{packet['exam_id']}.json", packet) + + index = { + "schema_version": QUESTION_BANK_SCHEMA, + "generated_at": timestamp_utc(), + "question_bank_path": portable_path(question_bank_path), + "packet_count": len(packets), + "packets": [ + { + "exam_id": packet["exam_id"], + "expected_questions": packet["expected_questions"], + "captured_questions": len(packet["captured_question_numbers"]), + "pending_questions": len(packet["pending_question_numbers"]), + "packet_path": portable_path(packet_dir / f"{packet['exam_id']}.json"), + } + for packet in packets + ], + } + _write_json(packet_dir / "index.json", index) + return index + + +def merge_review_drop( + *, + review_drop_path: Path, + question_bank_path: Path = QUESTION_BANK_FILE, +) -> dict[str, Any]: + review = _read_json(review_drop_path) + exam_id = _safe_str(review.get("exam_id")) + if not exam_id: + raise ValueError(f"Review drop missing exam_id: {review_drop_path}") + + question_bank = _read_json(question_bank_path) + target_exam = next( + (exam for exam in _safe_list(question_bank.get("exams")) if isinstance(exam, dict) and _safe_str(exam.get("exam_id")) == exam_id), + None, + ) + if target_exam is None: + raise ValueError(f"Exam not found in question bank: {exam_id}") + + questions_by_number = { + int(question["number"]): question + for question in _safe_list(target_exam.get("questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + blocked_by_number = { + int(question["number"]): question + for question in _safe_list(target_exam.get("blocked_questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + + for update in _safe_list(review.get("question_updates")): + if not isinstance(update, dict) or not str(update.get("number", "")).isdigit(): + continue + number = int(update["number"]) + existing = deepcopy(questions_by_number.get(number, {})) + provenance = { + "origin": "vision_review_drop", + "origin_path": portable_path(review_drop_path), + "capture_method": "vision_model_manual_review", + "review_status": _safe_str(_safe_dict(update.get("provenance")).get("review_status")) or "agent_reviewed_pending_human_confirmation", + "review_pass": int(_safe_dict(update.get("provenance")).get("review_pass") or 1), + "human_confirmed": bool(_safe_dict(update.get("provenance")).get("human_confirmed")), + "page_refs": _safe_list(_safe_dict(update.get("provenance")).get("page_refs")), + "notes": _safe_list(_safe_dict(update.get("provenance")).get("notes")), + } + questions_by_number[number] = { + "question_id": _question_id(exam_id, number), + "number": number, + "topic": _safe_str(update.get("topic")) or _safe_str(existing.get("topic")), + "question": _safe_str(update.get("question")) or _safe_str(existing.get("question")), + "options": _normalize_question_options(update.get("options")) or _normalize_question_options(existing.get("options")), + "correct": _safe_str(update.get("correct")) or _safe_str(existing.get("correct")), + "explanation": _safe_str(update.get("explanation")) or _safe_str(existing.get("explanation")), + "code_context": _safe_str(update.get("code_context")) or _safe_str(existing.get("code_context")), + "provenance": provenance, + } + blocked_by_number.pop(number, None) + + target_exam["questions"] = sorted(questions_by_number.values(), key=lambda item: int(item["number"])) + target_exam["blocked_questions"] = sorted(blocked_by_number.values(), key=lambda item: int(item["number"])) + target_exam["review_tracking"] = _review_tracking(target_exam["questions"], target_exam["blocked_questions"]) + target_exam["extraction_status"] = _exam_status(target_exam["review_tracking"]) + question_bank["generated_at"] = timestamp_utc() + _write_json(question_bank_path, question_bank) + return target_exam diff --git a/pipelines/vision_exam_pipeline_gemini.py b/pipelines/vision_exam_pipeline_gemini.py new file mode 100644 index 0000000..c70976e --- /dev/null +++ b/pipelines/vision_exam_pipeline_gemini.py @@ -0,0 +1,450 @@ +from __future__ import annotations + +import json +import re +import subprocess +from collections import defaultdict +from pathlib import Path +from typing import Any + +from pipelines.shared import ( + FAST_GEMINI_AGENT, + FAST_GEMINI_AGENT_FALLBACK, + SMART_GEMINI_AGENT, + SMART_GEMINI_AGENT_FALLBACK, + extract_json_blob, +) +from pipelines.vision_exam_pipeline_bank import merge_review_drop +from pipelines.vision_exam_pipeline_review import _evaluation_file, _write_evaluation_work_packets +from pipelines.vision_exam_pipeline_shared import ( + QUESTION_BANK_FILE, + REVIEW_DROP_DIR, + SELECTABLE_ITEMS_FILE, + _normalize_question_options, + _read_json, + _safe_dict, + _safe_list, + _safe_str, + _write_json, + portable_path, + timestamp_utc, +) + +ROOT = Path(__file__).resolve().parents[1] + + +def _model_chain(model: str) -> list[str]: + if model == SMART_GEMINI_AGENT: + return [SMART_GEMINI_AGENT, SMART_GEMINI_AGENT_FALLBACK] + if model == FAST_GEMINI_AGENT: + return [FAST_GEMINI_AGENT, FAST_GEMINI_AGENT_FALLBACK] + return [model] + + +def _run_gemini_json(prompt: str, *, model: str, timeout_seconds: int) -> dict[str, Any]: + last_error: Exception | None = None + for candidate in _model_chain(model): + try: + result = subprocess.run( + ["gemini", "-m", candidate, "-p", prompt], + text=True, + capture_output=True, + timeout=timeout_seconds, + ) + if result.returncode != 0: + details = (result.stderr or result.stdout or "no stdout/stderr captured").strip() + raise RuntimeError(f"Gemini failed ({result.returncode}): {details[:1200]}") + parsed = json.loads(extract_json_blob(result.stdout)) + if not isinstance(parsed, dict): + raise ValueError("Gemini output must be a JSON object.") + return parsed + except Exception as exc: # noqa: BLE001 + last_error = exc + raise RuntimeError(f"Gemini prompt failed after retries: {last_error}") + + +def _page_capture_prompt( + *, + exam_id: str, + title: str, + page_image_path: Path, + page_ref: str, + pending_numbers: list[int], +) -> str: + return f""" +You are performing a vision-only extraction from a rendered PNG of a Python exam solution page. + +Exam ID: {exam_id} +Exam title: {title} +Pending question numbers for this exam: {pending_numbers} +Image: @{page_image_path} + +Return ONLY one JSON object with EXACT shape: +{{ + "question_updates": [ + {{ + "number": 0, + "topic": "", + "question": "", + "options": {{"a": "", "b": "", "c": "", "d": ""}}, + "correct": "a", + "explanation": "", + "code_context": "", + "provenance": {{ + "review_status": "agent_reviewed_pending_human_confirmation", + "review_pass": 1, + "human_confirmed": false, + "page_refs": ["{page_ref}"], + "notes": ["Reviewed from rendered PNG pages only."] + }} + }} + ] +}} + +Rules: +- Use ONLY what is visible in the image. Do not use OCR, text layers, or any external context. +- Include only questions whose prompt, answer options, and marked correct answer are visible enough on this image to extract faithfully. +- If no pending question is fully extractable from this image, return {{"question_updates": []}}. +- Use lowercase option keys a/b/c/d. +- `topic` should be the short topic label from the question header, not the full header line. +- `correct` must be the visibly marked answer on the solution page. +- `explanation` should be concise and based only on the visible question and answer. +- `code_context` should contain the visible code block if the question includes one; otherwise "". +- `page_refs` must stay exactly ["{page_ref}"]. +- Add a short note in `provenance.notes` if any small detail is hard to read, instead of guessing silently. +""".strip() + + +def _normalize_capture_update(update: dict[str, Any], *, page_ref: str) -> dict[str, Any] | None: + if not isinstance(update, dict): + return None + number_text = str(update.get("number", "")).strip() + if not number_text.isdigit(): + return None + provenance = _safe_dict(update.get("provenance")) + page_refs = _safe_list(provenance.get("page_refs")) or [page_ref] + notes = [note for note in _safe_list(provenance.get("notes")) if _safe_str(note)] + if "Reviewed from rendered PNG pages only." not in notes: + notes.insert(0, "Reviewed from rendered PNG pages only.") + return { + "number": int(number_text), + "topic": _safe_str(update.get("topic")), + "question": _safe_str(update.get("question")), + "options": _normalize_question_options(update.get("options")), + "correct": _safe_str(update.get("correct")).lower(), + "explanation": _safe_str(update.get("explanation")), + "code_context": _safe_str(update.get("code_context")), + "provenance": { + "review_status": _safe_str(provenance.get("review_status")) or "agent_reviewed_pending_human_confirmation", + "review_pass": int(provenance.get("review_pass") or 1), + "human_confirmed": bool(provenance.get("human_confirmed")), + "page_refs": page_refs, + "notes": notes, + }, + } + + +def auto_capture_missing_questions( + *, + exam_ids: list[str] | None = None, + question_bank_path: Path = QUESTION_BANK_FILE, + model: str = SMART_GEMINI_AGENT, + timeout_seconds: int = 180, +) -> dict[str, Any]: + question_bank = _read_json(question_bank_path) + target_exam_ids = {exam_id for exam_id in (exam_ids or []) if exam_id} + results = [] + + for exam in _safe_list(question_bank.get("exams")): + if not isinstance(exam, dict): + continue + exam_id = _safe_str(exam.get("exam_id")) + if target_exam_ids and exam_id not in target_exam_ids: + continue + pending = { + int(item["number"]) + for item in _safe_list(exam.get("blocked_questions")) + if isinstance(item, dict) and str(item.get("number", "")).isdigit() + } + if not pending: + continue + captured: dict[int, dict[str, Any]] = {} + for page_ref in _safe_list(exam.get("page_image_paths")): + page_path = Path(page_ref) + if not page_path.is_absolute(): + page_path = (ROOT / page_ref).resolve() + if not page_path.exists(): + continue + prompt = _page_capture_prompt( + exam_id=exam_id, + title=_safe_str(exam.get("title")), + page_image_path=page_path, + page_ref=_safe_str(page_ref), + pending_numbers=sorted(pending), + ) + parsed = _run_gemini_json(prompt, model=model, timeout_seconds=timeout_seconds) + for raw_update in _safe_list(parsed.get("question_updates")): + update = _normalize_capture_update(raw_update, page_ref=_safe_str(page_ref)) + if not update: + continue + number = int(update["number"]) + if number in pending and number not in captured: + captured[number] = update + if pending and pending.issubset(set(captured)): + break + if not captured: + results.append({"exam_id": exam_id, "captured_questions": 0, "review_drop_path": "", "present_questions": len(_safe_list(exam.get("questions"))), "blocked_questions": len(_safe_list(exam.get("blocked_questions")))}) + continue + review_drop_path = REVIEW_DROP_DIR / f"{exam_id}-auto-gemini.json" + review_drop = { + "exam_id": exam_id, + "question_updates": [captured[number] for number in sorted(captured)], + } + _write_json(review_drop_path, review_drop) + merged_exam = merge_review_drop(review_drop_path=review_drop_path, question_bank_path=question_bank_path) + results.append( + { + "exam_id": exam_id, + "captured_questions": len(captured), + "review_drop_path": portable_path(review_drop_path), + "present_questions": int(_safe_dict(merged_exam.get("review_tracking")).get("present_questions") or 0), + "blocked_questions": int(_safe_dict(merged_exam.get("review_tracking")).get("blocked_questions") or 0), + } + ) + return { + "generated_at": timestamp_utc(), + "model": model, + "results": results, + } + + +_TOKEN_RE = re.compile(r"[a-zA-Z_]{3,}") + + +def _tokenize(text: str) -> set[str]: + return {token.lower() for token in _TOKEN_RE.findall(text or "")} + + +def _candidate_items_for_question( + *, + question: dict[str, Any], + selectable_items: list[dict[str, Any]], + limit: int = 18, +) -> list[dict[str, Any]]: + snapshot = _safe_dict(question.get("question_snapshot")) + seed_context = _safe_dict(question.get("seed_context")) + prioritized = { + _safe_str(item_id) + for item_id in _safe_list(seed_context.get("available_seed_snippet_ids")) + if _safe_str(item_id) + } + question_text = "\n".join( + [ + _safe_str(snapshot.get("topic")), + _safe_str(snapshot.get("question")), + json.dumps(_safe_dict(snapshot.get("options")), ensure_ascii=False), + _safe_str(snapshot.get("code_context")), + ] + ) + question_tokens = _tokenize(question_text) + scored = [] + for item in selectable_items: + if not isinstance(item, dict): + continue + item_id = _safe_str(item.get("item_id")) + item_text = " ".join( + [ + _safe_str(item.get("topic")), + _safe_str(item.get("subtopic_title")), + _safe_str(item.get("search_text")), + ] + ) + item_tokens = _tokenize(item_text) + overlap = len(question_tokens & item_tokens) + score = overlap + if item_id in prioritized: + score += 20 + if _safe_str(snapshot.get("topic")) and _safe_str(snapshot.get("topic")).lower() in item_text.lower(): + score += 4 + if item.get("bucket") == "recommended": + score += 2 + if item.get("item_type") in {"key_point", "key_point_detail", "ai_common_question"}: + score += 1 + scored.append((score, len(item_text), item)) + scored.sort(key=lambda row: (-row[0], row[1], _safe_str(row[2].get("item_id")))) + chosen = [row[2] for row in scored[:limit]] + return [ + { + "item_id": _safe_str(item.get("item_id")), + "week": int(item.get("week") or 0), + "item_type": _safe_str(item.get("item_type")), + "bucket": _safe_str(item.get("bucket")), + "topic": _safe_str(item.get("topic")), + "subtopic_title": _safe_str(item.get("subtopic_title")), + "search_text": _safe_str(item.get("search_text"))[:280], + } + for item in chosen + if _safe_str(item.get("item_id")) + ] + + +def _evaluation_prompt(*, question: dict[str, Any], candidates: list[dict[str, Any]]) -> str: + return f""" +You are evaluating which selectable snippets help a student answer a Python exam question with zero prior Python knowledge. + +Question JSON: +{json.dumps(_safe_dict(question.get("question_snapshot")), ensure_ascii=False)} + +Candidate selectable snippets: +{json.dumps(candidates, ensure_ascii=False)} + +Return ONLY one JSON object with EXACT keys: +{{ + "best_single_snippet": {{"item_id": "", "rationale": ""}}, + "top_three_snippets": [ + {{"item_id": "", "rationale": ""}} + ], + "minimal_sufficient_snippets": [ + {{"item_id": "", "rationale": ""}} + ], + "answerability": {{ + "status": "certain|partial|insufficient", + "confidence": "high|medium|low", + "rationale": "", + "usable_without_prior_python_knowledge": true + }}, + "gap_analysis": {{ + "summary": "", + "missing_concepts": [""], + "proposed_fix": "" + }}, + "suggested_changes": [ + {{ + "kind": "edit_existing|add_new", + "target_item_id": "", + "proposal": "", + "why_helpful": "", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this|consider_instead|skip" + }} + ] +}} + +Rules: +- Only choose `item_id` values that appear in the candidate list. +- `top_three_snippets` must contain 1-3 unique items. +- `minimal_sufficient_snippets` must contain 1-6 unique items. +- If the snippets are not enough, still choose the closest useful items and explain the gap. +- If no existing snippet should be edited, leave `target_item_id` as "" for an `add_new` suggestion. +- If no changes are needed, return `suggested_changes: []`. +- Keep rationales concise and specific. +""".strip() + + +def _normalize_ranked_snippets(values: Any, *, valid_ids: set[str], max_items: int) -> list[dict[str, Any]]: + items = [] + seen: set[str] = set() + for value in _safe_list(values): + entry = _safe_dict(value) + item_id = _safe_str(entry.get("item_id")) + if not item_id or item_id in seen or item_id not in valid_ids: + continue + seen.add(item_id) + items.append({"item_id": item_id, "rationale": _safe_str(entry.get("rationale"))}) + if len(items) >= max_items: + break + return items + + +def _normalize_suggested_changes(values: Any, *, valid_ids: set[str]) -> list[dict[str, Any]]: + items = [] + for value in _safe_list(values): + entry = _safe_dict(value) + kind = _safe_str(entry.get("kind")) + if kind not in {"edit_existing", "add_new"}: + continue + target_item_id = _safe_str(entry.get("target_item_id")) + if target_item_id and target_item_id not in valid_ids: + target_item_id = "" + items.append( + { + "kind": kind, + "target_item_id": target_item_id, + "proposal": _safe_str(entry.get("proposal")), + "why_helpful": _safe_str(entry.get("why_helpful")), + "why_maybe_unnecessary": _safe_str(entry.get("why_maybe_unnecessary")), + "recommended_direction": _safe_str(entry.get("recommended_direction")) or "consider_instead", + } + ) + return items + + +def auto_evaluate_questions( + *, + round_name: str, + model: str = FAST_GEMINI_AGENT, + timeout_seconds: int = 180, + limit: int = 0, + evaluation_path: Path | None = None, + selectable_items_path: Path = SELECTABLE_ITEMS_FILE, +) -> dict[str, Any]: + path = evaluation_path or _evaluation_file(round_name) + payload = _read_json(path) + selectable_items = _read_json(selectable_items_path) + valid_ids = {_safe_str(item.get("item_id")) for item in selectable_items if isinstance(item, dict) and _safe_str(item.get("item_id"))} + updated = 0 + for question in _safe_list(payload.get("questions")): + if not isinstance(question, dict): + continue + status = _safe_str(question.get("status")) + if status == "blocked_missing_question_capture": + continue + if status == "completed": + continue + candidates = _candidate_items_for_question(question=question, selectable_items=selectable_items) + parsed = _run_gemini_json( + _evaluation_prompt(question=question, candidates=candidates), + model=model, + timeout_seconds=timeout_seconds, + ) + best = _safe_dict(parsed.get("best_single_snippet")) + best_id = _safe_str(best.get("item_id")) + question["best_single_snippet"] = { + "item_id": best_id if best_id in valid_ids else "", + "rationale": _safe_str(best.get("rationale")), + } if best_id in valid_ids else None + question["top_three_snippets"] = _normalize_ranked_snippets(parsed.get("top_three_snippets"), valid_ids=valid_ids, max_items=3) + question["minimal_sufficient_snippets"] = _normalize_ranked_snippets(parsed.get("minimal_sufficient_snippets"), valid_ids=valid_ids, max_items=6) + answerability = _safe_dict(parsed.get("answerability")) + question["answerability"] = { + "status": _safe_str(answerability.get("status")) or "partial", + "confidence": _safe_str(answerability.get("confidence")) or "medium", + "rationale": _safe_str(answerability.get("rationale")), + "usable_without_prior_python_knowledge": bool(answerability.get("usable_without_prior_python_knowledge")), + } + gap = _safe_dict(parsed.get("gap_analysis")) + question["gap_analysis"] = { + "summary": _safe_str(gap.get("summary")), + "missing_concepts": [item for item in _safe_list(gap.get("missing_concepts")) if _safe_str(item)], + "proposed_fix": _safe_str(gap.get("proposed_fix")), + } + question["suggested_changes"] = _normalize_suggested_changes(parsed.get("suggested_changes"), valid_ids=valid_ids) + question["status"] = "completed" + review_meta = _safe_dict(question.get("review_meta")) + review_meta["requires_human_review"] = True + review_meta["reviewed_at"] = timestamp_utc() + review_meta["model"] = model + review_meta["candidate_item_count"] = len(candidates) + question["review_meta"] = review_meta + updated += 1 + if limit and updated >= limit: + break + payload["generated_at"] = timestamp_utc() + _write_json(path, payload) + _write_evaluation_work_packets(round_name=round_name, payload=payload) + return { + "generated_at": timestamp_utc(), + "model": model, + "updated_questions": updated, + "evaluation_path": portable_path(path), + } diff --git a/pipelines/vision_exam_pipeline_packet.py b/pipelines/vision_exam_pipeline_packet.py new file mode 100644 index 0000000..1efc849 --- /dev/null +++ b/pipelines/vision_exam_pipeline_packet.py @@ -0,0 +1,360 @@ +from __future__ import annotations + +from collections import Counter, defaultdict +from pathlib import Path +import re +from typing import Any + +from pipelines.vision_exam_pipeline_shared import ( + ANALYTICS_DIR, + EVALUATIONS_DIR, + REVIEW_PACKET_DIR, + REVIEW_PACKET_SCHEMA, + SELECTABLE_ITEMS_FILE, + SYNTHESIS_DIR, + _read_json, + _safe_dict, + _safe_list, + _safe_str, + _write_json, + portable_path, + timestamp_utc, +) + +THEME_SPECS = [ + ("strings_text_methods", "Strings, Indexing, and Text Methods", [r"\bstring", r"\bstrings", r"\bindex(?:ing)?\b", r"\bslic(?:e|ing)\b", r"\bsplit\b", r"\bjoin\b", r"\breplace\b", r"\bf-?string", r"\bislower\b", r"\bisupper\b", r"\bdigit"]), + ("loops_iteration", "Loops, Iteration, and Comprehensions", [r"\bfor loop", r"\bwhile loop", r"\bwhile\b", r"\brange\b", r"\bzip\b", r"\benumerate\b", r"\blist comprehension", r"\bcomprehension", r"\bparallel iteration", r"\bunpacking\b", r"\bappend\b"]), + ("functions_scope", "Functions, Returns, and Scope", [r"\breturn\b", r"\bprint\b", r"\bfunction", r"\bfunctions", r"\bargument", r"\barguments", r"\bscope\b", r"\bglobal\b", r"\blocal\b", r"\bunbound"]), + ("oop_self_attributes", "OOP, self, and Attributes", [r"\bself\b", r"\b__init__\b", r"\bclass\b", r"\bobject", r"\bobjects", r"\battribute", r"\battributes", r"\binstance", r"\bcompare method", r"\bcurrent instance"]), + ("pandas_core", "Pandas Core Operations", [r"\bpandas\b", r"\bdataframe\b", r"\bseries\b", r"\b\.loc\b", r"\b\.iloc\b", r"\bboolean mask", r"\bfiltering\b", r"\bcolumn\b", r"\bcolumns\b", r"\bdf\[", r"\bmap\(", r"\blambda\b"]), + ("datetime_time", "Datetime and Timedelta", [r"\bdatetime\b", r"\btimedelta\b", r"\bstrftime\b", r"\bstrptime\b", r"\bday of year\b", r"\bmonth\b", r"\byear\b"]), + ("dicts_tuples_sets", "Dictionaries, Tuples, and Sets", [r"\bdictionary", r"\bdictionaries", r"\bdict\b", r"\btuple", r"\btuples", r"\bset\b", r"\bsets\b", r"\b\.items\(\)", r"\bkey-value"]), + ("operators_boolean_logic", "Operators and Boolean Logic", [r"\bboolean\b", r"\btrue\b", r"\bfalse\b", r"\bfloor division\b", r"\b//\b", r"\blogic\b", r"\bcomparison\b", r"\bcondition", r"\bconditional expression", r"\bternary"]), + ("file_handling", "File Handling", [r"\bfile\b", r"\bopen\(", r"\bread mode\b", r"\bwrite mode\b", r"\bappend mode\b", r"\bfile handling"]), +] + + +def _packet_json_file(round_name: str) -> Path: + return REVIEW_PACKET_DIR / f"{round_name}.json" + + +def _packet_markdown_file(round_name: str) -> Path: + return REVIEW_PACKET_DIR / f"{round_name}.md" + + +def _analytics_file(round_name: str) -> Path: + return ANALYTICS_DIR / f"{round_name}.json" + + +def _synthesis_file(round_name: str) -> Path: + return SYNTHESIS_DIR / f"{round_name}.json" + + +def _evaluation_file(round_name: str) -> Path: + return EVALUATIONS_DIR / f"{round_name}.json" + + +def _classify_theme(text: str) -> tuple[str, str]: + lowered = text.lower() + for theme_id, theme_name, patterns in THEME_SPECS: + if any(re.search(pattern, lowered) for pattern in patterns): + return theme_id, theme_name + return "miscellaneous_exam_specific", "Miscellaneous Exam-Specific Gaps" + + +def _item_label(item: dict[str, Any]) -> str: + week = int(item.get("week") or 0) + topic = _safe_str(item.get("topic")) or "Unknown topic" + bucket = _safe_str(item.get("bucket")) or "unknown" + item_type = _safe_str(item.get("item_type")) or "unknown" + return f"Week {week} • {topic} • {bucket}/{item_type}" + + +def _item_excerpt(item: dict[str, Any]) -> str: + text = _safe_str(item.get("search_text")).replace("\n", " ") + text = re.sub(r"\s+", " ", text).strip() + return text[:180] + ("..." if len(text) > 180 else "") + + +def _priority_label(question_count: int, suggestion_count: int) -> str: + if question_count >= 8 or suggestion_count >= 12: + return "high" + if question_count >= 4 or suggestion_count >= 6: + return "medium" + return "selective" + + +def _snippet_usage(evaluations: list[dict[str, Any]], selectable_by_id: dict[str, dict[str, Any]]) -> list[dict[str, Any]]: + usage: dict[str, Counter[str]] = defaultdict(Counter) + for question in evaluations: + if _safe_str(question.get("status")) != "completed": + continue + best_id = _safe_str(_safe_dict(question.get("best_single_snippet")).get("item_id")) + if best_id in selectable_by_id: + usage[best_id]["best_single_count"] += 1 + for snippet in _safe_list(question.get("top_three_snippets")): + item_id = _safe_str(_safe_dict(snippet).get("item_id")) + if item_id in selectable_by_id: + usage[item_id]["top_three_count"] += 1 + for snippet in _safe_list(question.get("minimal_sufficient_snippets")): + item_id = _safe_str(_safe_dict(snippet).get("item_id")) + if item_id in selectable_by_id: + usage[item_id]["minimal_set_count"] += 1 + + rows = [] + for item_id, counts in usage.items(): + item = selectable_by_id[item_id] + weighted_score = int(counts["best_single_count"] * 3 + counts["minimal_set_count"] * 2 + counts["top_three_count"]) + rows.append( + { + "item_id": item_id, + "label": _item_label(item), + "excerpt": _item_excerpt(item), + "week": int(item.get("week") or 0), + "topic": _safe_str(item.get("topic")), + "bucket": _safe_str(item.get("bucket")), + "item_type": _safe_str(item.get("item_type")), + "best_single_count": int(counts["best_single_count"]), + "top_three_count": int(counts["top_three_count"]), + "minimal_set_count": int(counts["minimal_set_count"]), + "weighted_score": weighted_score, + } + ) + return sorted(rows, key=lambda row: (-row["weighted_score"], -row["best_single_count"], row["item_id"])) + + +def build_review_packet( + *, + round_name: str, + synthesis_payload: dict[str, Any], + analytics_payload: dict[str, Any], + evaluation_payload: dict[str, Any], + selectable_items: list[dict[str, Any]], +) -> tuple[dict[str, Any], str]: + selectable_by_id = {item["item_id"]: item for item in selectable_items if isinstance(item, dict) and item.get("item_id")} + completed = [item for item in _safe_list(evaluation_payload.get("questions")) if _safe_str(_safe_dict(item).get("status")) == "completed"] + answerability = Counter(_safe_str(_safe_dict(item.get("answerability")).get("status")) for item in completed) + + theme_map: dict[str, dict[str, Any]] = {} + for question in completed: + answerability_status = _safe_str(_safe_dict(question.get("answerability")).get("status")) + if answerability_status == "certain": + continue + gap_analysis = _safe_dict(question.get("gap_analysis")) + text = " ".join( + [ + _safe_str(gap_analysis.get("summary")), + " ".join(_safe_list(gap_analysis.get("missing_concepts"))), + _safe_str(gap_analysis.get("proposed_fix")), + ] + ).strip() + if not text: + continue + theme_id, theme_name = _classify_theme(text) + entry = theme_map.setdefault( + theme_id, + { + "theme_id": theme_id, + "theme_name": theme_name, + "question_ids": set(), + "partial_question_ids": set(), + "insufficient_question_ids": set(), + "suggestion_ids": set(), + "source_exams": set(), + "directions": Counter(), + "representative_gaps": [], + "representative_suggestions": [], + }, + ) + question_id = _safe_str(question.get("question_id")) + entry["question_ids"].add(question_id) + entry["source_exams"].add(_safe_str(question.get("exam_id"))) + if answerability_status == "partial": + entry["partial_question_ids"].add(question_id) + if answerability_status == "insufficient": + entry["insufficient_question_ids"].add(question_id) + gap_summary = _safe_str(gap_analysis.get("summary")) + if gap_summary and gap_summary not in entry["representative_gaps"] and len(entry["representative_gaps"]) < 3: + entry["representative_gaps"].append(gap_summary) + + for suggestion in _safe_list(synthesis_payload.get("suggestions")): + if not isinstance(suggestion, dict): + continue + text = " ".join( + [ + _safe_str(suggestion.get("proposal")), + " ".join(_safe_list(suggestion.get("pros"))), + " ".join(_safe_list(suggestion.get("cons"))), + ] + ).strip() + theme_id, theme_name = _classify_theme(text) + entry = theme_map.setdefault( + theme_id, + { + "theme_id": theme_id, + "theme_name": theme_name, + "question_ids": set(), + "partial_question_ids": set(), + "insufficient_question_ids": set(), + "suggestion_ids": set(), + "source_exams": set(), + "directions": Counter(), + "representative_gaps": [], + "representative_suggestions": [], + }, + ) + entry["suggestion_ids"].add(_safe_str(suggestion.get("suggestion_id"))) + entry["source_exams"].update(_safe_list(suggestion.get("source_exams"))) + entry["directions"][_safe_str(suggestion.get("recommended_direction")) or "consider_instead"] += 1 + proposal = _safe_str(suggestion.get("proposal")) + if proposal and proposal not in entry["representative_suggestions"] and len(entry["representative_suggestions"]) < 3: + entry["representative_suggestions"].append(proposal) + + theme_rows = [] + for entry in theme_map.values(): + question_count = len(entry["question_ids"]) + suggestion_count = len(entry["suggestion_ids"]) + if question_count == 0 and suggestion_count == 0: + continue + theme_rows.append( + { + "theme_id": entry["theme_id"], + "theme_name": entry["theme_name"], + "priority": _priority_label(question_count, suggestion_count), + "question_count": question_count, + "partial_question_count": len(entry["partial_question_ids"]), + "insufficient_question_count": len(entry["insufficient_question_ids"]), + "suggestion_count": suggestion_count, + "recommended_direction_counts": dict(entry["directions"]), + "source_exam_count": len({exam for exam in entry["source_exams"] if exam}), + "representative_gaps": entry["representative_gaps"], + "representative_suggestions": entry["representative_suggestions"], + } + ) + theme_rows.sort(key=lambda row: (-row["question_count"], -row["suggestion_count"], row["theme_name"])) + + snippet_rows = _snippet_usage(completed, selectable_by_id) + week_rows = _safe_list(analytics_payload.get("weeks")) + top_weeks = sorted(week_rows, key=lambda row: (-int(row.get("minimal_set_unique_snippets") or 0), int(row.get("week") or 0))) + review_sequence = [] + for index, row in enumerate(theme_rows[:10], start=1): + direction_counts = row["recommended_direction_counts"] + primary_direction = "add_this" if direction_counts.get("add_this", 0) >= direction_counts.get("consider_instead", 0) else "consider_instead" + review_sequence.append( + { + "order": index, + "theme_id": row["theme_id"], + "theme_name": row["theme_name"], + "priority": row["priority"], + "question_count": row["question_count"], + "suggestion_count": row["suggestion_count"], + "suggested_direction": primary_direction, + } + ) + + packet = { + "schema_version": REVIEW_PACKET_SCHEMA, + "generated_at": timestamp_utc(), + "round": round_name, + "ready_for_human_review": True, + "input_paths": { + "evaluations": portable_path(_evaluation_file(round_name)), + "synthesis": portable_path(_synthesis_file(round_name)), + "analytics": portable_path(_analytics_file(round_name)), + "selectable_items": portable_path(SELECTABLE_ITEMS_FILE), + }, + "summary": { + "completed_evaluations": len(completed), + "certain_count": int(answerability.get("certain", 0)), + "partial_count": int(answerability.get("partial", 0)), + "insufficient_count": int(answerability.get("insufficient", 0)), + "theme_count": len(theme_rows), + "top_snippet_count": len(snippet_rows), + }, + "review_sequence": review_sequence, + "themes": theme_rows, + "top_existing_snippets": snippet_rows[:20], + "week_summary": top_weeks, + "recommendations": { + "review_high_priority_themes_first": [row["theme_name"] for row in theme_rows if row["priority"] == "high"][:6], + "hold_off_on_implementation_until_human_review": True, + "likely_first_pass_focus": [row["theme_name"] for row in theme_rows[:5]], + }, + } + + lines = [ + f"# Review Packet ({round_name})", + "", + "## What Needs Your Review", + "", + "- This packet condenses the round-1 synthesis into review themes instead of 151 isolated suggestions.", + "- The goal is to decide which snippet edits/additions are worth implementing before the second evaluation round.", + f"- Completed evaluations: `{packet['summary']['completed_evaluations']}`", + f"- Answerability split: `certain={packet['summary']['certain_count']}`, `partial={packet['summary']['partial_count']}`, `insufficient={packet['summary']['insufficient_count']}`", + "", + "## Recommended Review Order", + "", + ] + for row in review_sequence: + lines.append( + f"{row['order']}. **{row['theme_name']}** (`priority={row['priority']}`, `questions={row['question_count']}`, `suggestions={row['suggestion_count']}`, `direction={row['suggested_direction']}`)" + ) + lines.extend(["", "## Priority Themes", ""]) + for row in theme_rows[:12]: + direction_counts = row["recommended_direction_counts"] + lines.append(f"### {row['theme_name']}") + lines.append("") + lines.append(f"- Priority: `{row['priority']}`") + lines.append(f"- Affected questions: `{row['question_count']}` (`partial={row['partial_question_count']}`, `insufficient={row['insufficient_question_count']}`)") + lines.append(f"- Related synthesized suggestions: `{row['suggestion_count']}`") + lines.append(f"- Suggested direction mix: `{direction_counts}`") + if row["representative_gaps"]: + lines.append("- Representative gaps:") + for gap in row["representative_gaps"]: + lines.append(f" - {gap}") + if row["representative_suggestions"]: + lines.append("- Representative suggestions:") + for proposal in row["representative_suggestions"]: + lines.append(f" - {proposal}") + lines.append("") + lines.extend(["## Strong Existing Snippets", "", "| Rank | Snippet | Best single | Top 3 | Minimal set |", "|---|---|---:|---:|---:|"]) + for index, row in enumerate(packet["top_existing_snippets"][:15], start=1): + lines.append( + f"| {index} | `{row['item_id']}`
    {row['label']} | {row['best_single_count']} | {row['top_three_count']} | {row['minimal_set_count']} |" + ) + lines.extend(["", "## Week Coverage Snapshot", "", "| Week | Top 1 unique | Top 3 unique | Minimal-set unique | Minimal-set unused |", "|---|---:|---:|---:|---:|"]) + for row in top_weeks: + lines.append( + f"| {row['week']} | {row['top1_unique_snippets']} | {row['top3_unique_snippets']} | {row['minimal_set_unique_snippets']} | {row['minimal_set_unused_snippets']} |" + ) + lines.extend( + [ + "", + "## Suggested Human Workflow", + "", + "1. Review the high-priority themes first and decide `add`, `edit existing`, or `skip`.", + "2. Use the representative suggestions as examples, not as a forced one-to-one implementation list.", + "3. Favor additions/edits that solve multiple question gaps rather than single-exam edge cases.", + "4. Only after that review should the implementation round begin.", + "", + ] + ) + return packet, "\n".join(lines) + + +def write_review_packet( + *, + round_name: str, + selectable_items_path: Path = SELECTABLE_ITEMS_FILE, +) -> dict[str, Any]: + packet, markdown = build_review_packet( + round_name=round_name, + synthesis_payload=_read_json(_synthesis_file(round_name)), + analytics_payload=_read_json(_analytics_file(round_name)), + evaluation_payload=_read_json(_evaluation_file(round_name)), + selectable_items=_read_json(selectable_items_path), + ) + _write_json(_packet_json_file(round_name), packet) + _packet_markdown_file(round_name).parent.mkdir(parents=True, exist_ok=True) + _packet_markdown_file(round_name).write_text(markdown + "\n", encoding="utf-8") + return packet diff --git a/pipelines/vision_exam_pipeline_review.py b/pipelines/vision_exam_pipeline_review.py new file mode 100644 index 0000000..7475319 --- /dev/null +++ b/pipelines/vision_exam_pipeline_review.py @@ -0,0 +1,498 @@ +from __future__ import annotations + +import json +from collections import Counter, defaultdict +from copy import deepcopy +from pathlib import Path +from typing import Any + +from pipelines.vision_exam_pipeline_shared import ( + ANALYTICS_DIR, + ANALYTICS_SCHEMA, + EVALUATIONS_DIR, + EVALUATION_SCHEMA, + EVALUATION_STATUSES, + QUESTION_BANK_FILE, + SELECTABLE_ITEMS_FILE, + SYNTHESIS_DIR, + SYNTHESIS_SCHEMA, + WORK_PACKET_DIR, + _card_week, + _normalize_question_options, + _read_json, + _safe_dict, + _safe_list, + _safe_str, + _write_json, + iter_selectable_items, + load_topic_cards, + portable_path, + timestamp_utc, +) + + +def build_selectable_items_snapshot( + *, + output_path: Path = SELECTABLE_ITEMS_FILE, +) -> list[dict[str, Any]]: + cards = load_topic_cards() + weeks_by_card = {card["id"]: _card_week(card) for card in cards if isinstance(card, dict) and card.get("id")} + items = [] + for item in iter_selectable_items(cards): + if isinstance(item, dict): + snapshot = dict(item) + snapshot["week"] = int(weeks_by_card.get(_safe_str(item.get("card_id"))) or 0) + items.append(snapshot) + _write_json(output_path, items) + return items + + +def _findings_index(findings_paths: list[Path]) -> dict[tuple[str, int], list[dict[str, Any]]]: + index: dict[tuple[str, int], list[dict[str, Any]]] = defaultdict(list) + for path in findings_paths: + if not path.exists(): + continue + for exam in _safe_list(_safe_dict(_read_json(path)).get("exams")): + exam_id = _safe_str(_safe_dict(exam).get("exam_id")) + for question in _safe_list(_safe_dict(exam).get("questions")): + if isinstance(question, dict) and str(question.get("question_number", "")).isdigit(): + index[(exam_id, int(question["question_number"]))].append(deepcopy(question)) + return index + +def _evaluation_file(round_name: str) -> Path: + return EVALUATIONS_DIR / f"{round_name}.json" + +def _evaluation_work_packet_dir(round_name: str) -> Path: + return WORK_PACKET_DIR / "evaluations" / round_name + +def _default_answerability() -> dict[str, Any]: + return {"status": "unknown", "confidence": "unknown", "rationale": "", "usable_without_prior_python_knowledge": False} + +def _default_gap_analysis() -> dict[str, Any]: + return {"summary": "", "missing_concepts": [], "proposed_fix": ""} + +def _evaluation_status_for_question(*, question: dict[str, Any], existing: dict[str, Any]) -> str: + existing_status = _safe_str(existing.get("status")) + if existing_status == "completed": + return existing_status + review_status = _safe_str(_safe_dict(question.get("provenance")).get("review_status")) + if review_status == "human_confirmed": + return "pending_review" + if review_status == "agent_reviewed_pending_human_confirmation": + return "captured_pending_human_confirmation" + if review_status == "seeded_legacy_needs_vision_review": + return "blocked_missing_question_capture" + return existing_status or "pending_review" + +def _gap_analysis_for_question(*, existing: dict[str, Any], status: str) -> dict[str, Any]: + existing_gap = _safe_dict(existing.get("gap_analysis")) + if existing_gap: + return existing_gap + if status == "captured_pending_human_confirmation": + return { + "summary": "Question has been captured with a vision review and is awaiting human confirmation before snippet evaluation.", + "missing_concepts": [], + "proposed_fix": "Human-confirm the captured question record, then complete the snippet evaluation.", + } + if status == "blocked_missing_question_capture": + return { + "summary": "Question still requires vision capture before snippet evaluation can begin.", + "missing_concepts": [], + "proposed_fix": "Capture the missing exam question with the vision-review workflow before snippet evaluation.", + } + return _default_gap_analysis() + +def build_evaluation_scaffold( + *, + round_name: str, + question_bank: dict[str, Any], + selectable_items: list[dict[str, Any]], + existing_payload: dict[str, Any] | None = None, + findings_paths: list[Path] | None = None, +) -> dict[str, Any]: + selectable_by_id = {item["item_id"]: item for item in selectable_items if isinstance(item, dict) and item.get("item_id")} + existing_questions = { + _safe_str(question.get("question_id")): question + for question in _safe_list(_safe_dict(existing_payload).get("questions")) + if isinstance(question, dict) + } + findings_index = _findings_index(findings_paths or []) + questions_payload = [] + + for exam in _safe_list(question_bank.get("exams")): + exam_id = _safe_str(_safe_dict(exam).get("exam_id")) + for question in _safe_list(_safe_dict(exam).get("questions")): + if not isinstance(question, dict): + continue + question_id = _safe_str(question.get("question_id")) + number = int(question["number"]) + existing = deepcopy(existing_questions.get(question_id, {})) + status = _evaluation_status_for_question(question=question, existing=existing) + questions_payload.append( + { + "evaluation_id": _safe_str(existing.get("evaluation_id")) or f"{round_name}:{question_id}", + "question_id": question_id, + "exam_id": exam_id, + "question_number": number, + "status": status, + "question_snapshot": { + "topic": _safe_str(question.get("topic")), + "question": _safe_str(question.get("question")), + "options": _normalize_question_options(question.get("options")), + "correct": _safe_str(question.get("correct")), + "explanation": _safe_str(question.get("explanation")), + "code_context": _safe_str(question.get("code_context")), + }, + "seed_context": { + "exact_match_findings": findings_index.get((exam_id, number), []), + "available_seed_snippet_ids": [ + item_id + for finding in findings_index.get((exam_id, number), []) + for item_id in _safe_list(_safe_dict(finding).get("evidence_item_ids")) + if item_id in selectable_by_id + ], + "provenance_review_status": _safe_str(_safe_dict(question.get("provenance")).get("review_status")), + }, + "best_single_snippet": existing.get("best_single_snippet"), + "top_three_snippets": _safe_list(existing.get("top_three_snippets")), + "minimal_sufficient_snippets": _safe_list(existing.get("minimal_sufficient_snippets")), + "answerability": _safe_dict(existing.get("answerability")) or _default_answerability(), + "gap_analysis": _gap_analysis_for_question(existing=existing, status=status), + "suggested_changes": _safe_list(existing.get("suggested_changes")), + "review_meta": {"requires_human_review": True, "reviewed_at": _safe_str(_safe_dict(existing.get("review_meta")).get("reviewed_at"))}, + } + ) + for blocked in _safe_list(_safe_dict(exam).get("blocked_questions")): + if not isinstance(blocked, dict): + continue + question_id = _safe_str(blocked.get("question_id")) + questions_payload.append( + { + "evaluation_id": f"{round_name}:{question_id}", + "question_id": question_id, + "exam_id": exam_id, + "question_number": int(blocked["number"]), + "status": "blocked_missing_question_capture", + "question_snapshot": {}, + "seed_context": { + "exact_match_findings": findings_index.get((exam_id, int(blocked["number"])), []), + "available_seed_snippet_ids": [], + "block_reason": _safe_str(blocked.get("reason")), + }, + "best_single_snippet": None, + "top_three_snippets": [], + "minimal_sufficient_snippets": [], + "answerability": _default_answerability(), + "gap_analysis": { + "summary": _safe_str(blocked.get("reason")), + "missing_concepts": [], + "proposed_fix": "Capture the missing exam question with the vision-review workflow before snippet evaluation.", + }, + "suggested_changes": [], + "review_meta": {"requires_human_review": True, "reviewed_at": ""}, + } + ) + + return { + "schema_version": EVALUATION_SCHEMA, + "generated_at": timestamp_utc(), + "round": round_name, + "question_bank_path": portable_path(QUESTION_BANK_FILE), + "selectable_items_path": portable_path(SELECTABLE_ITEMS_FILE), + "questions": sorted(questions_payload, key=lambda item: (_safe_str(item.get("exam_id")), int(item.get("question_number") or 0))), + } + +def _write_evaluation_work_packets(*, round_name: str, payload: dict[str, Any]) -> None: + output_dir = _evaluation_work_packet_dir(round_name) + questions_by_exam: dict[str, list[dict[str, Any]]] = defaultdict(list) + for question in _safe_list(payload.get("questions")): + if isinstance(question, dict): + questions_by_exam[_safe_str(question.get("exam_id"))].append(question) + for exam_id, questions in questions_by_exam.items(): + packet = { + "schema_version": EVALUATION_SCHEMA, + "generated_at": timestamp_utc(), + "round": round_name, + "exam_id": exam_id, + "question_count": len(questions), + "pending_question_ids": [question["question_id"] for question in questions if _safe_str(question.get("status")) == "pending_review"], + "captured_pending_human_confirmation_ids": [ + question["question_id"] + for question in questions + if _safe_str(question.get("status")) == "captured_pending_human_confirmation" + ], + "blocked_question_ids": [question["question_id"] for question in questions if _safe_str(question.get("status")) == "blocked_missing_question_capture"], + "questions": questions, + } + _write_json(output_dir / f"{exam_id}.json", packet) + +def write_evaluation_scaffold( + *, + round_name: str, + question_bank_path: Path = QUESTION_BANK_FILE, + selectable_items_path: Path = SELECTABLE_ITEMS_FILE, + findings_paths: list[Path] | None = None, +) -> dict[str, Any]: + question_bank = _read_json(question_bank_path) + selectable_items = _read_json(selectable_items_path) if selectable_items_path.exists() else build_selectable_items_snapshot() + output_path = _evaluation_file(round_name) + existing = _read_json(output_path) if output_path.exists() else None + payload = build_evaluation_scaffold( + round_name=round_name, + question_bank=question_bank, + selectable_items=selectable_items, + existing_payload=existing, + findings_paths=findings_paths, + ) + _write_json(output_path, payload) + _write_evaluation_work_packets(round_name=round_name, payload=payload) + return payload + +def validate_evaluation_payload(payload: dict[str, Any], *, selectable_items: list[dict[str, Any]]) -> list[str]: + errors = [] + valid_item_ids = {item["item_id"] for item in selectable_items if isinstance(item, dict) and item.get("item_id")} + seen_question_ids: set[str] = set() + for item in _safe_list(payload.get("questions")): + if not isinstance(item, dict): + errors.append("Evaluation question entry must be an object.") + continue + question_id = _safe_str(item.get("question_id")) + if not question_id: + errors.append("Evaluation question entry missing question_id.") + elif question_id in seen_question_ids: + errors.append(f"Duplicate evaluation question_id: {question_id}") + else: + seen_question_ids.add(question_id) + status = _safe_str(item.get("status")) + if status not in EVALUATION_STATUSES: + errors.append(f"{question_id or ''}: invalid evaluation status {status!r}") + for field in ["best_single_snippet"]: + snippet = item.get(field) + if isinstance(snippet, dict): + item_id = _safe_str(snippet.get("item_id")) + if item_id and item_id not in valid_item_ids: + errors.append(f"{question_id}: unknown snippet reference {item_id}") + for field in ["top_three_snippets", "minimal_sufficient_snippets"]: + for snippet in _safe_list(item.get(field)): + if isinstance(snippet, dict): + item_id = _safe_str(snippet.get("item_id")) + if item_id and item_id not in valid_item_ids: + errors.append(f"{question_id}: unknown snippet reference {item_id}") + for suggestion in _safe_list(item.get("suggested_changes")): + if isinstance(suggestion, dict): + target_item_id = _safe_str(suggestion.get("target_item_id")) + if target_item_id and target_item_id not in valid_item_ids: + errors.append(f"{question_id}: unknown target_item_id {target_item_id}") + return errors + + +def _synthesis_file(round_name: str) -> Path: + return SYNTHESIS_DIR / f"{round_name}.json" + + +def synthesize_suggestions(*, round_name: str, evaluation_path: Path | None = None) -> dict[str, Any]: + payload = _read_json(evaluation_path or _evaluation_file(round_name)) + grouped: dict[tuple[str, str, str], dict[str, Any]] = {} + for question in _safe_list(payload.get("questions")): + if not isinstance(question, dict): + continue + question_id = _safe_str(question.get("question_id")) + exam_id = _safe_str(question.get("exam_id")) + for suggestion in _safe_list(question.get("suggested_changes")): + if not isinstance(suggestion, dict): + continue + kind = _safe_str(suggestion.get("kind")) or "other" + target = _safe_str(suggestion.get("target_item_id")) + proposal = _safe_str(suggestion.get("proposal")) or _safe_str(suggestion.get("proposed_fix")) + key = (kind, target, proposal) + entry = grouped.setdefault( + key, + { + "suggestion_id": f"{round_name}:{len(grouped) + 1}", + "kind": kind, + "target_item_id": target, + "proposal": proposal, + "source_question_ids": [], + "source_exams": [], + "pros": [], + "cons": [], + "recommended_direction": _safe_str(suggestion.get("recommended_direction")) or "consider_instead", + "human_review_status": "pending", + }, + ) + if question_id and question_id not in entry["source_question_ids"]: + entry["source_question_ids"].append(question_id) + if exam_id and exam_id not in entry["source_exams"]: + entry["source_exams"].append(exam_id) + for key_name, field_name in [("pros", "why_helpful"), ("cons", "why_maybe_unnecessary")]: + value = _safe_str(suggestion.get(field_name)) + if value and value not in entry[key_name]: + entry[key_name].append(value) + + synthesis = { + "schema_version": SYNTHESIS_SCHEMA, + "generated_at": timestamp_utc(), + "round": round_name, + "requires_human_review": True, + "input_evaluations_path": portable_path(evaluation_path or _evaluation_file(round_name)), + "summary": { + "evaluation_count": len(_safe_list(payload.get("questions"))), + "completed_evaluation_count": sum(1 for question in _safe_list(payload.get("questions")) if _safe_str(_safe_dict(question).get("status")) == "completed"), + "suggestion_count": len(grouped), + }, + "suggestions": sorted(grouped.values(), key=lambda item: item["suggestion_id"]), + } + _write_json(_synthesis_file(round_name), synthesis) + return synthesis + + +def _analytics_file(round_name: str) -> Path: + return ANALYTICS_DIR / f"{round_name}.json" + + +def _analytics_report_file(round_name: str) -> Path: + return ANALYTICS_DIR / f"{round_name}.md" + + +def _comparison_summary(current: dict[str, Any], baseline: dict[str, Any]) -> dict[str, Any]: + current_counts = Counter(_safe_str(_safe_dict(item.get("answerability")).get("status")) for item in _safe_list(current.get("questions"))) + baseline_counts = Counter(_safe_str(_safe_dict(item.get("answerability")).get("status")) for item in _safe_list(baseline.get("questions"))) + return { + key: { + "current": int(current_counts.get(key, 0)), + "baseline": int(baseline_counts.get(key, 0)), + "delta": int(current_counts.get(key, 0) - baseline_counts.get(key, 0)), + } + for key in sorted(set(current_counts) | set(baseline_counts)) + if key + } + + +def build_ranking_analytics( + *, + round_name: str, + evaluation_payload: dict[str, Any], + selectable_items: list[dict[str, Any]], + baseline_payload: dict[str, Any] | None = None, +) -> tuple[dict[str, Any], str]: + selectable_by_id = {item["item_id"]: item for item in selectable_items if isinstance(item, dict) and item.get("item_id")} + completed = [item for item in _safe_list(evaluation_payload.get("questions")) if _safe_str(_safe_dict(item).get("status")) == "completed"] + status_counts = Counter(_safe_str(_safe_dict(item).get("status")) for item in _safe_list(evaluation_payload.get("questions"))) + answerability_counts = Counter(_safe_str(_safe_dict(item.get("answerability")).get("status")) for item in completed) + week_stats: dict[int, dict[str, set[str]]] = defaultdict(lambda: {"top1": set(), "top3": set(), "minimal": set(), "all": set()}) + + for item_id, item in selectable_by_id.items(): + week = int(item.get("week") or 0) + if week > 0: + week_stats[week]["all"].add(item_id) + for evaluation in completed: + best = _safe_dict(evaluation.get("best_single_snippet")) + item_id = _safe_str(best.get("item_id")) + if item_id in selectable_by_id: + week_stats[int(selectable_by_id[item_id].get("week") or 0)]["top1"].add(item_id) + for bucket_name, key in [("top_three_snippets", "top3"), ("minimal_sufficient_snippets", "minimal")]: + for snippet in _safe_list(evaluation.get(bucket_name)): + item_id = _safe_str(_safe_dict(snippet).get("item_id")) + if item_id in selectable_by_id: + week_stats[int(selectable_by_id[item_id].get("week") or 0)][key].add(item_id) + + weeks_payload = [] + for week in sorted(week for week in week_stats if week > 0): + stats = week_stats[week] + never_used = sorted(stats["all"] - stats["minimal"]) + weeks_payload.append( + { + "week": week, + "top1_unique_snippets": len(stats["top1"]), + "top3_unique_snippets": len(stats["top3"]), + "minimal_set_unique_snippets": len(stats["minimal"]), + "minimal_set_unused_snippets": len(never_used), + "unused_snippet_ids": never_used[:50], + } + ) + + insights = [] + if not completed: + insights.append("No completed question-to-snippet evaluations yet. Ranking decisions should wait until round reviews are filled in.") + elif weeks_payload: + top_week = max(weeks_payload, key=lambda row: row["minimal_set_unique_snippets"]) + insights.append(f"Week {top_week['week']} currently has the broadest minimal-set footprint with {top_week['minimal_set_unique_snippets']} unique snippets.") + + analytics = { + "schema_version": ANALYTICS_SCHEMA, + "generated_at": timestamp_utc(), + "round": round_name, + "input_evaluations_path": portable_path(_evaluation_file(round_name)), + "summary": { + "total_evaluations": len(_safe_list(evaluation_payload.get("questions"))), + "completed_evaluations": len(completed), + "status_counts": dict(status_counts), + "answerability_counts": dict(answerability_counts), + }, + "weeks": weeks_payload, + "insights": insights, + "comparison": _comparison_summary(evaluation_payload, baseline_payload or {}) if baseline_payload else {}, + } + + lines = [ + f"# Ranking Analytics ({round_name})", + "", + f"- Total evaluations: `{analytics['summary']['total_evaluations']}`", + f"- Completed evaluations: `{analytics['summary']['completed_evaluations']}`", + f"- Status counts: `{json.dumps(analytics['summary']['status_counts'], ensure_ascii=False, sort_keys=True)}`", + ] + if analytics["summary"]["answerability_counts"]: + lines.append(f"- Answerability counts: `{json.dumps(analytics['summary']['answerability_counts'], ensure_ascii=False, sort_keys=True)}`") + lines.extend(["", "## Week Summary", ""]) + if weeks_payload: + lines.append("| Week | Top 1 unique | Top 3 unique | Minimal-set unique | Minimal-set unused |") + lines.append("|---|---:|---:|---:|---:|") + for row in weeks_payload: + lines.append(f"| {row['week']} | {row['top1_unique_snippets']} | {row['top3_unique_snippets']} | {row['minimal_set_unique_snippets']} | {row['minimal_set_unused_snippets']} |") + else: + lines.append("No completed evaluations yet.") + if insights: + lines.extend(["", "## Insights", ""]) + for insight in insights: + lines.append(f"- {insight}") + return analytics, "\n".join(lines) + "\n" + + +def write_ranking_analytics( + *, + round_name: str, + baseline_round: str = "", + selectable_items_path: Path = SELECTABLE_ITEMS_FILE, +) -> dict[str, Any]: + evaluations = _read_json(_evaluation_file(round_name)) + selectable_items = _read_json(selectable_items_path) if selectable_items_path.exists() else build_selectable_items_snapshot() + baseline = _read_json(_evaluation_file(baseline_round)) if baseline_round and _evaluation_file(baseline_round).exists() else None + analytics, markdown = build_ranking_analytics( + round_name=round_name, + evaluation_payload=evaluations, + selectable_items=selectable_items, + baseline_payload=baseline, + ) + _write_json(_analytics_file(round_name), analytics) + _analytics_report_file(round_name).parent.mkdir(parents=True, exist_ok=True) + _analytics_report_file(round_name).write_text(markdown, encoding="utf-8") + return analytics + + +def validate_all( + *, + question_bank_path: Path = QUESTION_BANK_FILE, + selectable_items_path: Path = SELECTABLE_ITEMS_FILE, + evaluation_round: str = "", +) -> list[str]: + from pipelines.vision_exam_pipeline_shared import validate_question_bank_payload + + errors = [] + if question_bank_path.exists(): + errors.extend(validate_question_bank_payload(_read_json(question_bank_path))) + if evaluation_round: + evaluation_path = _evaluation_file(evaluation_round) + if evaluation_path.exists(): + selectable = _read_json(selectable_items_path) + errors.extend(validate_evaluation_payload(_read_json(evaluation_path), selectable_items=selectable)) + return errors diff --git a/pipelines/vision_exam_pipeline_shared.py b/pipelines/vision_exam_pipeline_shared.py new file mode 100644 index 0000000..eb1d634 --- /dev/null +++ b/pipelines/vision_exam_pipeline_shared.py @@ -0,0 +1,187 @@ +from __future__ import annotations + +import json +import re +from datetime import datetime, timezone +from pathlib import Path +from typing import Any + +from pipelines.shared import load_study_db +from scripts.exam_coverage_audit import ( + DEFAULT_TMP_DIR as AUDIT_TMP_DIR, + EXAM_SOURCES, + ROOT, + iter_selectable_items, + load_topic_cards, + portable_path, + render_exam_pages, + unique_exam_sources, +) + +DATA_ROOT = ROOT / "data" / "vision_exam_pipeline" +TMP_ROOT = ROOT / "tmp" / "vision_exam_pipeline" +LEGACY_ASSESSMENT_DIR = ROOT / "data" / "import_payloads" / "post_midterm_assessments" + +PAGE_MANIFEST_FILE = DATA_ROOT / "page_manifest.json" +QUESTION_BANK_FILE = DATA_ROOT / "exam_question_bank.json" +COMPLETENESS_FILE = DATA_ROOT / "exam_question_bank_completeness.json" +SELECTABLE_ITEMS_FILE = DATA_ROOT / "selectable_items_snapshot.json" +REVIEW_DROP_DIR = DATA_ROOT / "review_drops" +EVALUATIONS_DIR = DATA_ROOT / "evaluations" +SYNTHESIS_DIR = DATA_ROOT / "synthesis" +ANALYTICS_DIR = DATA_ROOT / "analytics" +REVIEW_PACKET_DIR = DATA_ROOT / "review_packets" +WORK_PACKET_DIR = DATA_ROOT / "work_packets" + +QUESTION_BANK_SCHEMA = "1.0" +PAGE_MANIFEST_SCHEMA = "1.0" +EVALUATION_SCHEMA = "1.0" +SYNTHESIS_SCHEMA = "1.0" +ANALYTICS_SCHEMA = "1.0" +REVIEW_PACKET_SCHEMA = "1.0" + +REVIEW_STATUSES = { + "seeded_legacy_needs_vision_review", + "pending_vision_review", + "agent_reviewed_pending_human_confirmation", + "human_confirmed", +} +EVALUATION_STATUSES = { + "pending_review", + "captured_pending_human_confirmation", + "blocked_missing_question_capture", + "completed", +} + + +def timestamp_utc() -> str: + return datetime.now(timezone.utc).replace(microsecond=0).isoformat().replace("+00:00", "Z") + + +def _safe_list(value: Any) -> list[Any]: + return value if isinstance(value, list) else [] + + +def _safe_dict(value: Any) -> dict[str, Any]: + return value if isinstance(value, dict) else {} + + +def _safe_str(value: Any) -> str: + return str(value or "").strip() + + +def _slugify(value: Any) -> str: + text = _safe_str(value).lower() + text = re.sub(r"[^a-z0-9]+", "-", text) + return re.sub(r"-+", "-", text).strip("-") + + +def _ensure_parent(path: Path) -> None: + path.parent.mkdir(parents=True, exist_ok=True) + + +def _write_json(path: Path, payload: dict[str, Any] | list[Any]) -> Path: + _ensure_parent(path) + path.write_text(json.dumps(payload, ensure_ascii=False, indent=2), encoding="utf-8") + return path + + +def _read_json(path: Path) -> Any: + return json.loads(path.read_text(encoding="utf-8")) + + +def _card_week(card: dict[str, Any]) -> int: + explicit = card.get("topic_meta", {}) if isinstance(card.get("topic_meta"), dict) else {} + try: + week = int(explicit.get("week")) + if week > 0: + return week + except (TypeError, ValueError): + pass + for value in _safe_list(card.get("weeks")): + try: + week = int(value) + except (TypeError, ValueError): + continue + if week > 0: + return week + return 0 + + +def duplicate_exam_aliases() -> list[dict[str, Any]]: + aliases = [] + for exam in EXAM_SOURCES: + duplicate_of = _safe_str(exam.get("duplicate_of")) + if not duplicate_of: + continue + aliases.append( + { + "exam_id": exam["exam_id"], + "duplicate_of": duplicate_of, + "title": exam["title"], + "pdf_path": portable_path(Path(exam["pdf_path"])), + } + ) + return aliases + + +def _existing_page_paths(exam_id: str) -> list[Path]: + for directory in [AUDIT_TMP_DIR / "pages" / exam_id, TMP_ROOT / "pages" / exam_id]: + pages = sorted(directory.glob("page-*.png")) + if pages: + return pages + return [] + + +def _question_id(exam_id: str, number: int) -> str: + return f"{exam_id}-q{number:02d}" + + +def _normalize_question_options(options: Any) -> dict[str, str]: + if not isinstance(options, dict): + return {} + return {str(key).strip(): _safe_str(value) for key, value in options.items() if _safe_str(value)} + + +def _default_blocked_question(exam_id: str, number: int) -> dict[str, Any]: + return { + "question_id": _question_id(exam_id, number), + "number": number, + "status": "pending_vision_review", + "reason": "No reviewed question record exists yet. Capture this question from the rendered page PNGs with a vision model.", + } + + +def validate_question_bank_payload(payload: dict[str, Any]) -> list[str]: + errors = [] + seen_exam_ids: set[str] = set() + for exam in _safe_list(payload.get("exams")): + if not isinstance(exam, dict): + errors.append("Exam entry must be an object.") + continue + exam_id = _safe_str(exam.get("exam_id")) + if not exam_id: + errors.append("Exam entry missing exam_id.") + elif exam_id in seen_exam_ids: + errors.append(f"Duplicate exam_id: {exam_id}") + else: + seen_exam_ids.add(exam_id) + expected = int(exam.get("expected_questions") or 0) + question_numbers = { + int(question["number"]) + for question in _safe_list(exam.get("questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + blocked_numbers = { + int(question["number"]) + for question in _safe_list(exam.get("blocked_questions")) + if isinstance(question, dict) and str(question.get("number", "")).isdigit() + } + if question_numbers & blocked_numbers: + errors.append(f"{exam_id}: same question number present in questions and blocked_questions") + if expected and len(question_numbers | blocked_numbers) != expected: + errors.append(f"{exam_id}: expected {expected} accounted question slots, found {len(question_numbers | blocked_numbers)}") + for blocked in _safe_list(exam.get("blocked_questions")): + if isinstance(blocked, dict) and not _safe_str(blocked.get("reason")): + errors.append(f"{exam_id}: blocked question {blocked.get('number')} is missing a reason") + return errors diff --git a/scripts/vision_exam_pipeline.py b/scripts/vision_exam_pipeline.py new file mode 100644 index 0000000..8a8341a --- /dev/null +++ b/scripts/vision_exam_pipeline.py @@ -0,0 +1,223 @@ +#!/usr/bin/env python3 + +from __future__ import annotations + +import argparse +import json +from pathlib import Path +import sys + +ROOT = Path(__file__).resolve().parents[1] +if str(ROOT) not in sys.path: + sys.path.insert(0, str(ROOT)) + +from pipelines.shared.model_defaults import FAST_GEMINI_AGENT, SMART_GEMINI_AGENT + +from pipelines.vision_exam_pipeline import ( + COMPLETENESS_FILE, + PAGE_MANIFEST_FILE, + QUESTION_BANK_FILE, + REVIEW_DROP_DIR, + SELECTABLE_ITEMS_FILE, + TMP_ROOT, + auto_capture_missing_questions, + auto_evaluate_questions, + build_selectable_items_snapshot, + merge_review_drop, + prepare_page_manifest, + seed_question_bank, + synthesize_suggestions, + validate_all, + write_completeness_report, + write_extraction_packets, + write_evaluation_scaffold, + write_ranking_analytics, + write_review_packet, +) + + +def _parse_args() -> argparse.Namespace: + parser = argparse.ArgumentParser(description="Vision-first exam curation and snippet value pipeline.") + subparsers = parser.add_subparsers(dest="command", required=True) + + prepare = subparsers.add_parser("prepare-pages", help="Render or reuse exam page PNGs and write a persistent manifest.") + prepare.add_argument("--tmp-dir", type=Path, default=TMP_ROOT) + prepare.add_argument("--manifest-path", type=Path, default=PAGE_MANIFEST_FILE) + prepare.add_argument("--dpi", type=int, default=160) + prepare.add_argument("--overwrite", action="store_true") + + seed_bank = subparsers.add_parser("seed-question-bank", help="Seed the persistent question bank from legacy assessment payloads.") + seed_bank.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) + seed_bank.add_argument("--page-manifest-path", type=Path, default=PAGE_MANIFEST_FILE) + + completeness = subparsers.add_parser("audit-completeness", help="Write a completeness manifest for the current question bank.") + completeness.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) + completeness.add_argument("--report-path", type=Path, default=COMPLETENESS_FILE) + completeness.add_argument("--strict", action="store_true", help="Exit non-zero if any canonical exam is incomplete.") + + extraction = subparsers.add_parser("dispatch-extraction", help="Build per-exam extraction work packets for vision reviewers.") + extraction.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) + + auto_capture = subparsers.add_parser("auto-capture-missing", help="Use Gemini vision to extract missing questions from rendered PNG pages.") + auto_capture.add_argument("--exam-id", action="append", default=[], help="Optional exam_id filter. Repeat to process multiple exams.") + auto_capture.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) + auto_capture.add_argument("--review-drop-dir", type=Path, default=REVIEW_DROP_DIR) + auto_capture.add_argument("--model", default=SMART_GEMINI_AGENT) + auto_capture.add_argument("--timeout-seconds", type=int, default=180) + + merge = subparsers.add_parser("merge-review-drop", help="Merge one agent-produced vision review file into the canonical question bank.") + merge.add_argument("--input", type=Path, required=True, help="Path to one review-drop JSON file.") + merge.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) + + dispatch = subparsers.add_parser("dispatch-evaluations", help="Build or refresh a resumable evaluation scaffold for one round.") + dispatch.add_argument("--round", required=True, help="Round identifier, for example round1 or round2.") + dispatch.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) + dispatch.add_argument("--selectable-items-path", type=Path, default=SELECTABLE_ITEMS_FILE) + dispatch.add_argument( + "--findings", + type=Path, + action="append", + default=[], + help="Optional audit findings JSON files used to seed candidate exact-match snippet IDs.", + ) + + auto_evaluate = subparsers.add_parser("auto-evaluate", help="Use Gemini to fill first-pass snippet evaluations for captured questions.") + auto_evaluate.add_argument("--round", required=True) + auto_evaluate.add_argument("--model", default=FAST_GEMINI_AGENT) + auto_evaluate.add_argument("--timeout-seconds", type=int, default=180) + auto_evaluate.add_argument("--limit", type=int, default=0, help="Optional cap on number of questions to evaluate in this run.") + auto_evaluate.add_argument("--selectable-items-path", type=Path, default=SELECTABLE_ITEMS_FILE) + + synth = subparsers.add_parser("synthesize-suggestions", help="Group suggested snippet edits/additions from one evaluation round.") + synth.add_argument("--round", required=True) + + analytics = subparsers.add_parser("generate-ranking-analytics", help="Build analytics and a Markdown report for one evaluation round.") + analytics.add_argument("--round", required=True) + analytics.add_argument("--baseline-round", default="", help="Optional earlier round to compare against.") + analytics.add_argument("--selectable-items-path", type=Path, default=SELECTABLE_ITEMS_FILE) + + review_packet = subparsers.add_parser("generate-review-packet", help="Build a human-friendly review packet for one evaluation round.") + review_packet.add_argument("--round", required=True) + review_packet.add_argument("--selectable-items-path", type=Path, default=SELECTABLE_ITEMS_FILE) + + validate = subparsers.add_parser("validate", help="Validate question-bank and evaluation snippet references.") + validate.add_argument("--evaluation-round", default="", help="Optional evaluation round to validate.") + validate.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) + validate.add_argument("--selectable-items-path", type=Path, default=SELECTABLE_ITEMS_FILE) + + return parser.parse_args() + + +def main() -> int: + args = _parse_args() + if args.command == "prepare-pages": + payload = prepare_page_manifest( + tmp_dir=args.tmp_dir, + manifest_path=args.manifest_path, + dpi=args.dpi, + overwrite=args.overwrite, + ) + print(json.dumps({"manifest_path": str(args.manifest_path), "exam_count": len(payload["exams"])})) + return 0 + + if args.command == "seed-question-bank": + payload = seed_question_bank( + question_bank_path=args.question_bank_path, + page_manifest_path=args.page_manifest_path, + ) + print(json.dumps({"question_bank_path": str(args.question_bank_path), "exam_count": len(payload["exams"])})) + return 0 + + if args.command == "audit-completeness": + report = write_completeness_report( + question_bank_path=args.question_bank_path, + report_path=args.report_path, + ) + print(json.dumps({"report_path": str(args.report_path), "overall_status": report["overall_status"]})) + return 1 if args.strict and report["overall_status"] != "complete" else 0 + + if args.command == "dispatch-extraction": + payload = write_extraction_packets(question_bank_path=args.question_bank_path) + print(json.dumps({"packet_count": payload["packet_count"]})) + return 0 + + if args.command == "auto-capture-missing": + payload = auto_capture_missing_questions( + exam_ids=args.exam_id, + question_bank_path=args.question_bank_path, + model=args.model, + timeout_seconds=args.timeout_seconds, + ) + print(json.dumps(payload, ensure_ascii=False)) + return 0 + + if args.command == "merge-review-drop": + payload = merge_review_drop(review_drop_path=args.input, question_bank_path=args.question_bank_path) + print(json.dumps({"exam_id": payload["exam_id"], "present_questions": payload["review_tracking"]["present_questions"], "blocked_questions": payload["review_tracking"]["blocked_questions"]})) + return 0 + + if args.command == "dispatch-evaluations": + if not args.selectable_items_path.exists(): + build_selectable_items_snapshot(output_path=args.selectable_items_path) + payload = write_evaluation_scaffold( + round_name=args.round, + question_bank_path=args.question_bank_path, + selectable_items_path=args.selectable_items_path, + findings_paths=args.findings, + ) + print(json.dumps({"evaluation_path": str(ROOT / "data" / "vision_exam_pipeline" / "evaluations" / f"{args.round}.json"), "question_count": len(payload["questions"])})) + return 0 + + if args.command == "auto-evaluate": + if not args.selectable_items_path.exists(): + build_selectable_items_snapshot(output_path=args.selectable_items_path) + payload = auto_evaluate_questions( + round_name=args.round, + model=args.model, + timeout_seconds=args.timeout_seconds, + limit=args.limit, + selectable_items_path=args.selectable_items_path, + ) + print(json.dumps(payload, ensure_ascii=False)) + return 0 + + if args.command == "synthesize-suggestions": + payload = synthesize_suggestions(round_name=args.round) + print(json.dumps({"suggestion_count": payload["summary"]["suggestion_count"]})) + return 0 + + if args.command == "generate-ranking-analytics": + if not args.selectable_items_path.exists(): + build_selectable_items_snapshot(output_path=args.selectable_items_path) + payload = write_ranking_analytics( + round_name=args.round, + baseline_round=args.baseline_round, + selectable_items_path=args.selectable_items_path, + ) + print(json.dumps({"analytics_path": str(ROOT / "data" / "vision_exam_pipeline" / "analytics" / f"{args.round}.json"), "completed_evaluations": payload["summary"]["completed_evaluations"]})) + return 0 + + if args.command == "generate-review-packet": + if not args.selectable_items_path.exists(): + build_selectable_items_snapshot(output_path=args.selectable_items_path) + payload = write_review_packet( + round_name=args.round, + selectable_items_path=args.selectable_items_path, + ) + print(json.dumps({"review_packet_path": str(ROOT / "data" / "vision_exam_pipeline" / "review_packets" / f"{args.round}.md"), "theme_count": payload["summary"]["theme_count"]})) + return 0 + + errors = validate_all( + question_bank_path=args.question_bank_path, + selectable_items_path=args.selectable_items_path, + evaluation_round=args.evaluation_round, + ) + if errors: + print(json.dumps({"status": "fail", "errors": errors}, ensure_ascii=False, indent=2)) + return 1 + print(json.dumps({"status": "pass"})) + return 0 + + +if __name__ == "__main__": + raise SystemExit(main()) diff --git a/tests/test_vision_exam_pipeline.py b/tests/test_vision_exam_pipeline.py new file mode 100644 index 0000000..59b7605 --- /dev/null +++ b/tests/test_vision_exam_pipeline.py @@ -0,0 +1,465 @@ +from __future__ import annotations + +import json +from pathlib import Path +import tempfile +import unittest + +from pipelines import vision_exam_pipeline as pipeline + + +class VisionExamPipelineTests(unittest.TestCase): + def test_duplicate_aliases_keep_canonical_exam_set_unique(self) -> None: + aliases = pipeline.duplicate_exam_aliases() + canonical_ids = {exam["exam_id"] for exam in pipeline.unique_exam_sources()} + self.assertTrue(aliases) + self.assertEqual(7, len(canonical_ids)) + self.assertNotIn(aliases[0]["exam_id"], canonical_ids) + self.assertIn(aliases[0]["duplicate_of"], canonical_ids) + + def test_completeness_report_marks_blocked_questions_incomplete(self) -> None: + report = pipeline.build_completeness_report( + { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "title": "Demo Exam", + "expected_questions": 2, + "questions": [ + { + "question_id": "demo-exam-q01", + "number": 1, + "provenance": {"human_confirmed": True}, + } + ], + "blocked_questions": [ + { + "question_id": "demo-exam-q02", + "number": 2, + "status": "pending_vision_review", + "reason": "Not reviewed yet.", + } + ], + } + ], + } + ) + self.assertEqual("incomplete", report["overall_status"]) + self.assertEqual(1, report["summary"]["incomplete_exam_count"]) + + def test_completeness_report_allows_unconfirmed_but_fully_captured_exam(self) -> None: + report = pipeline.build_completeness_report( + { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "title": "Demo Exam", + "expected_questions": 2, + "questions": [ + { + "question_id": "demo-exam-q01", + "number": 1, + "provenance": {"human_confirmed": False}, + }, + { + "question_id": "demo-exam-q02", + "number": 2, + "provenance": {"human_confirmed": False}, + }, + ], + "blocked_questions": [], + } + ], + } + ) + self.assertEqual("complete", report["overall_status"]) + self.assertEqual(1, report["summary"]["complete_exam_count"]) + self.assertEqual(0, report["summary"]["incomplete_exam_count"]) + self.assertEqual(0, report["exams"][0]["human_confirmed_questions"]) + + def test_build_evaluation_scaffold_preserves_existing_completed_review(self) -> None: + question_bank = { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "questions": [ + { + "question_id": "demo-exam-q01", + "number": 1, + "topic": "Loops", + "question": "What prints?", + "options": {"a": "1", "b": "2"}, + "correct": "a", + "explanation": "Because.", + "code_context": "print(1)", + "provenance": {"review_status": "human_confirmed"}, + } + ], + "blocked_questions": [], + } + ], + } + selectable_items = [{"item_id": "snippet-1", "week": 2}] + existing = { + "questions": [ + { + "evaluation_id": "round1:demo-exam-q01", + "question_id": "demo-exam-q01", + "status": "completed", + "best_single_snippet": {"item_id": "snippet-1", "why": "Exact match"}, + "top_three_snippets": [{"item_id": "snippet-1", "why": "Only item"}], + "minimal_sufficient_snippets": [{"item_id": "snippet-1", "why": "Enough"}], + "answerability": {"status": "fully_answerable"}, + "gap_analysis": {"summary": ""}, + "suggested_changes": [], + "review_meta": {"reviewed_at": "2026-03-23T10:00:00Z"}, + } + ] + } + payload = pipeline.build_evaluation_scaffold( + round_name="round1", + question_bank=question_bank, + selectable_items=selectable_items, + existing_payload=existing, + findings_paths=[], + ) + question = payload["questions"][0] + self.assertEqual("completed", question["status"]) + self.assertEqual("snippet-1", question["best_single_snippet"]["item_id"]) + self.assertEqual("2026-03-23T10:00:00Z", question["review_meta"]["reviewed_at"]) + + def test_build_evaluation_scaffold_marks_missing_question_capture_as_blocked(self) -> None: + question_bank = { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "questions": [], + "blocked_questions": [ + { + "question_id": "demo-exam-q02", + "number": 2, + "status": "pending_vision_review", + "reason": "Need page review.", + } + ], + } + ], + } + payload = pipeline.build_evaluation_scaffold( + round_name="round1", + question_bank=question_bank, + selectable_items=[], + existing_payload=None, + findings_paths=[], + ) + question = payload["questions"][0] + self.assertEqual("blocked_missing_question_capture", question["status"]) + self.assertIn("Need page review.", question["gap_analysis"]["summary"]) + + def test_build_evaluation_scaffold_marks_agent_captured_questions_as_pending_confirmation(self) -> None: + question_bank = { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "questions": [ + { + "question_id": "demo-exam-q01", + "number": 1, + "topic": "demo", + "question": "What is 1 + 1?", + "options": {"a": "2"}, + "correct": "a", + "explanation": "Basic arithmetic.", + "provenance": {"review_status": "agent_reviewed_pending_human_confirmation"}, + } + ], + "blocked_questions": [], + } + ], + } + existing_payload = { + "questions": [ + { + "question_id": "demo-exam-q01", + "status": "blocked_missing_question_capture", + } + ] + } + payload = pipeline.build_evaluation_scaffold( + round_name="round1", + question_bank=question_bank, + selectable_items=[], + existing_payload=existing_payload, + findings_paths=[], + ) + question = payload["questions"][0] + self.assertEqual("captured_pending_human_confirmation", question["status"]) + self.assertIn("awaiting human confirmation", question["gap_analysis"]["summary"]) + + def test_validate_evaluation_payload_rejects_unknown_snippet_ids(self) -> None: + errors = pipeline.validate_evaluation_payload( + { + "questions": [ + { + "question_id": "demo-exam-q01", + "status": "completed", + "best_single_snippet": {"item_id": "missing-snippet"}, + "top_three_snippets": [], + "minimal_sufficient_snippets": [], + "suggested_changes": [], + } + ] + }, + selectable_items=[{"item_id": "snippet-1"}], + ) + self.assertTrue(errors) + self.assertIn("missing-snippet", errors[0]) + + def test_build_ranking_analytics_tracks_week_counts_and_comparison(self) -> None: + evaluation_payload = { + "questions": [ + { + "question_id": "q1", + "status": "completed", + "answerability": {"status": "fully_answerable"}, + "best_single_snippet": {"item_id": "snippet-1"}, + "top_three_snippets": [{"item_id": "snippet-1"}, {"item_id": "snippet-2"}], + "minimal_sufficient_snippets": [{"item_id": "snippet-2"}], + }, + { + "question_id": "q2", + "status": "pending_review", + "answerability": {"status": "unknown"}, + "best_single_snippet": None, + "top_three_snippets": [], + "minimal_sufficient_snippets": [], + }, + ] + } + baseline_payload = { + "questions": [ + { + "question_id": "q1", + "status": "completed", + "answerability": {"status": "partial"}, + "best_single_snippet": {"item_id": "snippet-1"}, + "top_three_snippets": [], + "minimal_sufficient_snippets": [], + } + ] + } + selectable_items = [ + {"item_id": "snippet-1", "week": 1}, + {"item_id": "snippet-2", "week": 1}, + {"item_id": "snippet-3", "week": 2}, + ] + analytics, markdown = pipeline.build_ranking_analytics( + round_name="round2", + evaluation_payload=evaluation_payload, + selectable_items=selectable_items, + baseline_payload=baseline_payload, + ) + self.assertEqual(1, analytics["summary"]["completed_evaluations"]) + self.assertEqual(1, analytics["weeks"][0]["top1_unique_snippets"]) + self.assertEqual(1, analytics["comparison"]["fully_answerable"]["delta"]) + self.assertIn("Week Summary", markdown) + + def test_build_review_packet_surfaces_themes_and_top_snippets(self) -> None: + synthesis_payload = { + "suggestions": [ + { + "suggestion_id": "round1:1", + "proposal": "Add a snippet explaining string slicing and split().", + "pros": ["Helps with string parsing questions."], + "cons": [], + "recommended_direction": "add_this", + "source_exams": ["exam-a"], + }, + { + "suggestion_id": "round1:2", + "proposal": "Create a datetime cheat-sheet snippet using strptime and timedelta.", + "pros": ["Reduces guessing on datetime questions."], + "cons": [], + "recommended_direction": "add_this", + "source_exams": ["exam-b"], + }, + ] + } + analytics_payload = { + "weeks": [ + { + "week": 4, + "top1_unique_snippets": 2, + "top3_unique_snippets": 4, + "minimal_set_unique_snippets": 3, + "minimal_set_unused_snippets": 1, + } + ] + } + evaluation_payload = { + "questions": [ + { + "question_id": "q1", + "exam_id": "exam-a", + "status": "completed", + "answerability": {"status": "partial"}, + "gap_analysis": { + "summary": "Student needs string indexing and split rules.", + "missing_concepts": ["string slicing"], + "proposed_fix": "Add a string methods summary snippet.", + }, + "best_single_snippet": {"item_id": "snippet-1"}, + "top_three_snippets": [{"item_id": "snippet-1"}], + "minimal_sufficient_snippets": [{"item_id": "snippet-1"}], + }, + { + "question_id": "q2", + "exam_id": "exam-b", + "status": "completed", + "answerability": {"status": "insufficient"}, + "gap_analysis": { + "summary": "Student lacks datetime parsing rules.", + "missing_concepts": ["datetime.strptime"], + "proposed_fix": "Add a datetime and timedelta summary card.", + }, + "best_single_snippet": {"item_id": "snippet-2"}, + "top_three_snippets": [{"item_id": "snippet-2"}], + "minimal_sufficient_snippets": [{"item_id": "snippet-2"}], + }, + ] + } + selectable_items = [ + {"item_id": "snippet-1", "week": 4, "topic": "Strings", "bucket": "recommended", "item_type": "source_exam", "search_text": "String slicing and split example."}, + {"item_id": "snippet-2", "week": 6, "topic": "Datetime", "bucket": "recommended", "item_type": "source_exam", "search_text": "Datetime parsing example."}, + ] + + packet, markdown = pipeline.build_review_packet( + round_name="round1", + synthesis_payload=synthesis_payload, + analytics_payload=analytics_payload, + evaluation_payload=evaluation_payload, + selectable_items=selectable_items, + ) + + self.assertEqual(2, packet["summary"]["completed_evaluations"]) + theme_names = {theme["theme_name"] for theme in packet["themes"]} + self.assertIn("Strings, Indexing, and Text Methods", theme_names) + self.assertIn("Datetime and Timedelta", theme_names) + self.assertTrue(packet["top_existing_snippets"]) + self.assertIn("Recommended Review Order", markdown) + self.assertIn("Strong Existing Snippets", markdown) + + def test_validate_question_bank_payload_requires_reasoned_blocked_slots(self) -> None: + errors = pipeline.validate_question_bank_payload( + { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "expected_questions": 1, + "questions": [], + "blocked_questions": [{"question_id": "demo-exam-q01", "number": 1, "status": "pending_vision_review"}], + } + ], + } + ) + self.assertTrue(errors) + self.assertIn("missing a reason", errors[0]) + + def test_write_extraction_packets_tracks_captured_and_pending_questions(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + question_bank_path = Path(tmp) / "exam_question_bank.json" + output_dir = Path(tmp) / "packets" + question_bank_path.write_text( + json.dumps( + { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "title": "Demo Exam", + "expected_questions": 2, + "pdf_path": "demo.pdf", + "page_image_paths": ["tmp/demo/page-01.png"], + "questions": [{"question_id": "demo-exam-q01", "number": 1}], + "blocked_questions": [ + { + "question_id": "demo-exam-q02", + "number": 2, + "status": "pending_vision_review", + "reason": "Need capture.", + } + ], + } + ], + } + ), + encoding="utf-8", + ) + index = pipeline.write_extraction_packets(question_bank_path=question_bank_path, output_dir=output_dir) + + self.assertEqual(1, index["packet_count"]) + self.assertEqual(1, index["packets"][0]["captured_questions"]) + self.assertEqual(1, index["packets"][0]["pending_questions"]) + + def test_merge_review_drop_promotes_blocked_question_into_question_bank(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + question_bank_path = Path(tmp) / "exam_question_bank.json" + review_drop_path = Path(tmp) / "review_drop.json" + question_bank_path.write_text( + json.dumps( + { + "schema_version": "1.0", + "exams": [ + { + "exam_id": "demo-exam", + "title": "Demo Exam", + "expected_questions": 1, + "questions": [], + "blocked_questions": [ + { + "question_id": "demo-exam-q01", + "number": 1, + "status": "pending_vision_review", + "reason": "Need capture.", + } + ], + } + ], + } + ), + encoding="utf-8", + ) + review_drop_path.write_text( + json.dumps( + { + "exam_id": "demo-exam", + "question_updates": [ + { + "number": 1, + "topic": "Loops", + "question": "What prints?", + "options": {"a": "1", "b": "2"}, + "correct": "a", + "explanation": "Because.", + "provenance": {"page_refs": ["tmp/page-01.png"]}, + } + ], + } + ), + encoding="utf-8", + ) + merged_exam = pipeline.merge_review_drop(review_drop_path=review_drop_path, question_bank_path=question_bank_path) + + self.assertEqual(1, merged_exam["review_tracking"]["present_questions"]) + self.assertEqual(0, merged_exam["review_tracking"]["blocked_questions"]) + self.assertEqual("Loops", merged_exam["questions"][0]["topic"]) + + +if __name__ == "__main__": + unittest.main() From e9dfda80395d837ac45dc5cd803db1c4e506689b Mon Sep 17 00:00:00 2001 From: caspersimon <165684406+caspersimon@users.noreply.github.com> Date: Tue, 24 Mar 2026 01:40:26 +0100 Subject: [PATCH 3/6] Add overnight runbooks and pipeline status for snippet curation --- AGENTS.md | 23 ++ .../OVERNIGHT_EXECUTION_BOARD.md | 73 ++++++ data/vision_exam_pipeline/README.md | 11 + data/vision_exam_pipeline/RUNBOOK.md | 36 +++ docs/ARCHITECTURE.md | 6 + docs/ROADMAP.md | 1 + docs/TESTING.md | 7 + docs/VISION_EXAM_PIPELINE.md | 167 +++++++++++++ docs/curation/OVERNIGHT_AGENT_RUNBOOK.md | 192 +++++++++++++++ ...NIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md | 229 ++++++++++++++++++ ...009-vision-first-exam-curation-pipeline.md | 26 +- pipelines/vision_exam_pipeline.py | 4 + pipelines/vision_exam_pipeline_status.py | 123 ++++++++++ scripts/vision_exam_pipeline.py | 8 + tests/test_vision_exam_pipeline.py | 85 ------- tests/test_vision_exam_pipeline_followup.py | 169 +++++++++++++ 16 files changed, 1073 insertions(+), 87 deletions(-) create mode 100644 data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md create mode 100644 data/vision_exam_pipeline/RUNBOOK.md create mode 100644 docs/VISION_EXAM_PIPELINE.md create mode 100644 docs/curation/OVERNIGHT_AGENT_RUNBOOK.md create mode 100644 docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md create mode 100644 pipelines/vision_exam_pipeline_status.py create mode 100644 tests/test_vision_exam_pipeline_followup.py diff --git a/AGENTS.md b/AGENTS.md index c762b3d..c8f08f6 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,6 +10,29 @@ Technical handoff for coding agents and contributors working on this repository. - No backend/runtime services required - Source dataset and generated card data are JSON files in repo +## Current Overnight Focus + +If the active task is the post-synthesis snippet completeness round, start here first: + +- `docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md` +- `docs/curation/OVERNIGHT_AGENT_RUNBOOK.md` +- `data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md` +- `data/vision_exam_pipeline/plan_after_manual_synthesis.md` +- `data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md` + +Quick state command: + +```bash +python3 scripts/vision_exam_pipeline.py status --round round1 +``` + +Important for this phase: + +- optimize for snippet completeness, not UI/topic architecture changes +- treat metadata architecture ideas as future-facing only for now +- be conservative about pruning before the next grading pass +- do not use OCR, `pdftotext`, or deterministic text extraction for exam question capture in the vision exam pipeline + ## Current Snapshot (2026-03-22) - `topic_cards.json`: **27 total cards** diff --git a/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md b/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md new file mode 100644 index 0000000..ab5bf53 --- /dev/null +++ b/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md @@ -0,0 +1,73 @@ +# Overnight Execution Board + +Mutable coordination surface for the snippet-completeness phase. + +Primary checklist: + +- [SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md) + +Runbook: + +- [OVERNIGHT_AGENT_RUNBOOK.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/docs/curation/OVERNIGHT_AGENT_RUNBOOK.md) + +## Current Objective + +Implement approved completeness improvements from the manual synthesis round without drifting into UI/topic-architecture refactors. + +## State Snapshot + +Refresh with: + +```bash +python3 scripts/vision_exam_pipeline.py status --round round1 +``` + +## Cluster Tracker + +- [ ] Essential String Methods and Indexing Reference +- [ ] Output Formatting and String Construction +- [ ] Boolean String Predicates +- [ ] Iteration Helpers and Basic Operator Traps +- [ ] Comprehension Syntax Reference +- [ ] Dictionary Construction and Iteration Patterns +- [ ] Pandas Selection and Indexing Rules +- [ ] Pandas Filtering, Aggregation, and Column Arithmetic (expand existing) +- [ ] Lambda, `map`, and `apply` +- [ ] Datetime Parse/Format + object-vs-string arithmetic reference family +- [ ] OOP Fundamentals +- [ ] OOP Comparison Logic (add or merge into existing) +- [ ] Flexible Arguments, Returns, and `kwargs` +- [ ] Return-Value and Scope Cleanup (edit existing) +- [ ] Exact-Match Retrieval Fixes (light and fair only) + +## In Progress + +- Owner: +- Cluster: +- Files: +- Notes: + +## Completed + +- Timestamp: +- Cluster: +- Summary: +- Validation: + +## Blockers / Risks + +- None yet. + +## Handoff Template + +Use this format: + +```text +Timestamp: +Completed: +In progress: +Files touched: +Validation run: +Open risks: +Suggested next cluster: +``` diff --git a/data/vision_exam_pipeline/README.md b/data/vision_exam_pipeline/README.md index 6f7ead6..1c8a567 100644 --- a/data/vision_exam_pipeline/README.md +++ b/data/vision_exam_pipeline/README.md @@ -13,6 +13,16 @@ Key files: - `analytics/.json` and `analytics/.md`: ranking-prep summaries - `work_packets/extractions/*.json`: per-exam capture packets - `work_packets/evaluations//*.json`: per-exam evaluation packets +- `OVERNIGHT_EXECUTION_BOARD.md`: mutable coordination board for the current snippet-completeness phase + +Execution docs: + +- `data/vision_exam_pipeline/RUNBOOK.md` +- `docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md` +- `docs/curation/OVERNIGHT_AGENT_RUNBOOK.md` +- `docs/VISION_EXAM_PIPELINE.md` +- `data/vision_exam_pipeline/plan_after_manual_synthesis.md` +- `data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md` Workflow: @@ -25,6 +35,7 @@ python3 scripts/vision_exam_pipeline.py dispatch-evaluations --round round1 --fi python3 scripts/vision_exam_pipeline.py synthesize-suggestions --round round1 python3 scripts/vision_exam_pipeline.py generate-ranking-analytics --round round1 python3 scripts/vision_exam_pipeline.py generate-review-packet --round round1 +python3 scripts/vision_exam_pipeline.py status --round round1 python3 scripts/vision_exam_pipeline.py validate --evaluation-round round1 ``` diff --git a/data/vision_exam_pipeline/RUNBOOK.md b/data/vision_exam_pipeline/RUNBOOK.md new file mode 100644 index 0000000..ae28798 --- /dev/null +++ b/data/vision_exam_pipeline/RUNBOOK.md @@ -0,0 +1,36 @@ +# Vision Pipeline Runbook + +Start here if you are operating the current snippet-completeness round from inside `data/vision_exam_pipeline/`. + +## Read In This Order + +1. [OVERNIGHT_EXECUTION_BOARD.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md) +2. [plan_after_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/plan_after_manual_synthesis.md) +3. [round1_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md) +4. [SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md) +5. [OVERNIGHT_AGENT_RUNBOOK.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/docs/curation/OVERNIGHT_AGENT_RUNBOOK.md) +6. [VISION_EXAM_PIPELINE.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/docs/VISION_EXAM_PIPELINE.md) + +## Quick State Check + +```bash +python3 scripts/vision_exam_pipeline.py status --round round1 +``` + +## Current Priority + +Improve snippet completeness. + +Do not: + +- start the topic-first UI refactor +- aggressively prune the corpus before the next grading pass +- cross the human review gates automatically + +## Canonical Validation + +Before handoff or after integrating meaningful work: + +```bash +make leave-better +``` diff --git a/docs/ARCHITECTURE.md b/docs/ARCHITECTURE.md index dda49cb..ef8de3f 100644 --- a/docs/ARCHITECTURE.md +++ b/docs/ARCHITECTURE.md @@ -75,6 +75,12 @@ Raw material ingestion for post-midterm content is also available through: - `scripts/validate_extracted_material.py` - `scripts/import_extracted_materials.py` +Important boundary: + +- the raw-ingestion pipeline may use OCR/text extraction fallbacks for messy source material +- the separate vision-first exam curation pipeline must not use OCR, `pdftotext`, or deterministic text-layer extraction for exam question capture +- see `docs/VISION_EXAM_PIPELINE.md` and `data/vision_exam_pipeline/README.md` for the exam-specific workflow + Testing/QA automation: - `scripts/smoke_ui_playwright.js`: browser smoke flow + screenshot/probe generation. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 93a365e..08c6721 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -24,6 +24,7 @@ Current implementation handoff: | RM-006 | Medium | planned | Topic Explorer UX | Continue densifying the Topic Explorer sidebar and source rails so long weeks remain fast to scan without layout bloat. | [Template](./specs/SPEC_TEMPLATE.md) | | RM-007 | Medium | planned | Topic curation | Merge the densest remaining topic clusters inside the new course-outline buckets without losing evidence quality. | [RM-007](./specs/RM-007-course-outline-topic-merging.md) | | RM-008 | High | in_progress | Exam discoverability | Surface exact exam-match snippets in the right topic rails, reduce critical reliance on `additional`, and evaluate making high-value `ai_summary` content selectable. | [RM-008](./specs/RM-008-exam-snippet-discoverability.md) | +| RM-009 | High | in_progress | Vision exam pipeline | Keep the vision-first exam workflow resumable and use it to drive the current completeness-first snippet curation round. | [RM-009](./specs/RM-009-vision-first-exam-curation-pipeline.md) | ## Triage Rules diff --git a/docs/TESTING.md b/docs/TESTING.md index 6ee1a96..fd9f39f 100644 --- a/docs/TESTING.md +++ b/docs/TESTING.md @@ -87,6 +87,12 @@ The existing render packet remains the practical starting point for this workflo See [RM-009 Vision-First Exam Curation Pipeline](specs/RM-009-vision-first-exam-curation-pipeline.md) for the implementation contract and review checkpoints. +Current execution docs for the snippet-completeness follow-up round: + +- `docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md` +- `docs/curation/OVERNIGHT_AGENT_RUNBOOK.md` +- `data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md` + Current entrypoint: ```bash @@ -98,6 +104,7 @@ python3 scripts/vision_exam_pipeline.py dispatch-evaluations --round round1 --fi python3 scripts/vision_exam_pipeline.py synthesize-suggestions --round round1 python3 scripts/vision_exam_pipeline.py generate-ranking-analytics --round round1 python3 scripts/vision_exam_pipeline.py generate-review-packet --round round1 +python3 scripts/vision_exam_pipeline.py status --round round1 python3 scripts/vision_exam_pipeline.py validate --evaluation-round round1 ``` diff --git a/docs/VISION_EXAM_PIPELINE.md b/docs/VISION_EXAM_PIPELINE.md new file mode 100644 index 0000000..e49c566 --- /dev/null +++ b/docs/VISION_EXAM_PIPELINE.md @@ -0,0 +1,167 @@ +# Vision Exam Pipeline + +Operator-facing map of the vision-first exam pipeline. + +Use this when you need to understand: + +- which module owns which part of the pipeline +- which artifacts are durable vs disposable +- which states are safe to continue from +- where the human review gates are + +## Purpose + +The vision exam pipeline is the repo’s exam-review workflow for: + +- rendering exam PDFs to PNG pages +- capturing canonical question/answer records from those PNGs +- grading the current snippet corpus against those questions +- producing synthesis and analytics for later curation + +This pipeline is separate from the broader raw-ingestion pipeline. + +Important boundary: + +- the broader raw-ingestion pipeline may use OCR/text extraction for other source types +- the vision exam pipeline must not use OCR, `pdftotext`, or deterministic text-layer extraction for exam capture + +## Module Map + +- [scripts/vision_exam_pipeline.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/scripts/vision_exam_pipeline.py) + Thin CLI entrypoint for the pipeline. + +- [pipelines/vision_exam_pipeline.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/pipelines/vision_exam_pipeline.py) + Re-export surface for pipeline helpers. + +- [pipelines/vision_exam_pipeline_shared.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/pipelines/vision_exam_pipeline_shared.py) + Shared constants, paths, IDs, safe helpers, and validation primitives. + +- [pipelines/vision_exam_pipeline_bank.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/pipelines/vision_exam_pipeline_bank.py) + Page manifest prep, bank seeding, completeness reporting, extraction packets, and review-drop merge logic. + +- [pipelines/vision_exam_pipeline_gemini.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/pipelines/vision_exam_pipeline_gemini.py) + Gemini-based auto-capture and auto-evaluation helpers. + +- [pipelines/vision_exam_pipeline_review.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/pipelines/vision_exam_pipeline_review.py) + Evaluation scaffold generation, validation, synthesis, and analytics. + +- [pipelines/vision_exam_pipeline_packet.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/pipelines/vision_exam_pipeline_packet.py) + Human-facing review packet generation. + +- [pipelines/vision_exam_pipeline_status.py](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/pipelines/vision_exam_pipeline_status.py) + Current-state summary for resumable supervision. + +## Durable vs Disposable Artifacts + +### Durable + +These are system-of-record or checkpoint artifacts: + +- `data/vision_exam_pipeline/exam_question_bank.json` +- `data/vision_exam_pipeline/exam_question_bank_completeness.json` +- `data/vision_exam_pipeline/selectable_items_snapshot.json` +- `data/vision_exam_pipeline/evaluations/.json` +- `data/vision_exam_pipeline/synthesis/.json` +- `data/vision_exam_pipeline/analytics/.json` +- `data/vision_exam_pipeline/review_packets/.json` +- `data/vision_exam_pipeline/review_packets/.md` +- `data/vision_exam_pipeline/review_packets/_manual_synthesis.md` + +### Semi-Durable + +Useful inputs or reusable working artifacts: + +- `data/vision_exam_pipeline/page_manifest.json` +- `data/vision_exam_pipeline/review_drops/*.json` +- `data/vision_exam_pipeline/work_packets/extractions/*.json` +- `data/vision_exam_pipeline/work_packets/evaluations//*.json` + +### Disposable / Regenerable Inputs + +- `tmp/exam_coverage_audit/manifest.json` +- `tmp/exam_coverage_audit/selectable_items.json` +- `tmp/exam_coverage_audit/pages//page-XX.png` + +## State Machine + +### Question Bank Review Status + +- `seeded_legacy_needs_vision_review` + Legacy-seeded content exists, but still requires vision review. + +- `pending_vision_review` + No reviewed question record exists yet. + +- `agent_reviewed_pending_human_confirmation` + A vision review has been merged, but not yet human-confirmed. + +- `human_confirmed` + Fully reviewed and human-confirmed. + +### Evaluation Status + +- `blocked_missing_question_capture` + Question capture is still missing. + +- `captured_pending_human_confirmation` + Question exists and may be graded, but the bank item is still awaiting human confirmation. + +- `pending_review` + Eligible for grading but not yet completed. + +- `completed` + Grading for that question is filled in. + +## Human Gates + +Human review is required: + +- after synthesis/review-packet generation and before snippet implementation +- after the snippet implementation round and before final ranking/category/UI decisions + +Do not automatically cross those gates in unattended runs. + +## Safe Operator Loop + +Use this order: + +1. `prepare-pages` +2. `seed-question-bank` +3. `audit-completeness` +4. `dispatch-extraction` +5. capture and merge review drops until blocked count is zero +6. `dispatch-evaluations` +7. complete evaluations for the target round +8. `synthesize-suggestions` +9. `generate-ranking-analytics` +10. `generate-review-packet` +11. `status` +12. stop at the human gate + +## Resume Command + +```bash +python3 scripts/vision_exam_pipeline.py status --round round1 +``` + +That command is the fastest way to see: + +- question-bank completeness +- evaluation-round completion +- whether synthesis/analytics/review packets exist +- the next gate + +## Parallelism Rules + +Safe to parallelize: + +- page-level or exam-level vision review work that emits separate review-drop files +- read-only analysis +- bounded snippet/content work with disjoint write scopes + +Do not parallelize direct writes to canonical files: + +- `exam_question_bank.json` +- `evaluations/.json` + +Use a single supervisor/integrator for canonical writes. diff --git a/docs/curation/OVERNIGHT_AGENT_RUNBOOK.md b/docs/curation/OVERNIGHT_AGENT_RUNBOOK.md new file mode 100644 index 0000000..cec9651 --- /dev/null +++ b/docs/curation/OVERNIGHT_AGENT_RUNBOOK.md @@ -0,0 +1,192 @@ +# Overnight Agent Runbook + +This runbook is for unsupervised overnight execution of the snippet-completeness phase. + +Primary objective: + +- improve snippet completeness end-to-end +- keep the work resumable +- avoid drifting into premature architecture/UI refactors + +Primary checklist: + +- [SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md) + +Execution board: + +- [OVERNIGHT_EXECUTION_BOARD.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md) + +## Recommended Automation Pattern + +Use a supervisor-worker loop, not one giant prompt. + +Good fit: + +- a Ralph-style loop +- or any similar recurring supervisor agent pattern + +Why: + +- the work is multi-phase +- there are natural checkpoints +- the repo already has resumable pipeline artifacts +- independent workers need bounded scopes to avoid stepping on each other + +## Recommended Topology + +### One Supervisor + +The supervisor should own: + +- reading the checklist +- checking current state +- choosing the next cluster +- assigning workers with disjoint scopes +- integrating results +- running validation +- updating the execution board + +The supervisor should not: + +- blindly re-scan the whole repo every loop +- hand workers vague goals like “improve snippets” +- start UI/data-model refactors during this phase + +### Two To Four Workers + +Suggested worker scopes: + +- worker A: strings, formatting, predicates, indexing +- worker B: loops, operators, comprehensions, dictionaries +- worker C: pandas, lambda, datetime +- worker D: OOP, returns, scope, flexible arguments, light retrieval cleanup + +If multiple workers are active: + +- give them disjoint write scopes whenever possible +- if they must touch the same file, stagger those tasks instead of parallelizing them + +## Supervisor Loop + +Repeat this cycle: + +1. Read: + - the execution checklist + - the execution board + - `python3 scripts/vision_exam_pipeline.py status --round round1` +2. Pick one or more unchecked clusters. +3. Delegate bounded work to workers. +4. Wait only when blocked on results. +5. Review and integrate changes. +6. Run targeted tests, then `make leave-better`. +7. Update the execution board with: + - what finished + - what is in progress + - what remains + - any blockers or quality concerns +8. Start the next loop. + +## Guardrails + +Always: + +- use the current checklist as the source of execution truth +- keep the focus on snippet completeness +- preserve breadth unless something is clearly redundant or weak +- prefer compact reference pieces plus optional explanation pieces +- keep exact-match search improvements fair and light + +Never: + +- use OCR or deterministic text extraction for exam capture +- pivot into topic-first UI work during this phase +- hard-prune aggressively before the next grading pass +- reward bloat by creating lots of tiny selectable pieces + +## Suggested Supervisor Prompt Shape + +Use something like: + +```text +You are the overnight supervisor for the snippet-completeness phase. + +First read: +- docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md +- data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md +- data/vision_exam_pipeline/plan_after_manual_synthesis.md +- data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md + +Then run: +- python3 scripts/vision_exam_pipeline.py status --round round1 + +Your job is to: +- choose the next unchecked high-value cluster(s) +- delegate bounded tasks to workers +- integrate results +- run validation +- update the execution board + +Do not start UI/topic-architecture refactors in this phase. +Do not aggressively prune the corpus before the next grading pass. +``` + +## Suggested Worker Prompt Shape + +```text +You own only this cluster: . + +Read: +- docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md +- data/vision_exam_pipeline/plan_after_manual_synthesis.md +- data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md + +Your task: +- implement only the approved snippet additions/edits for this cluster +- keep snippets concise and cheat-sheet optimized +- split selectable pieces only when users may reasonably want one without the other +- avoid drifting into unrelated cleanup + +Before finishing: +- summarize exactly what changed +- note any overlap risk with other clusters +- do not touch UI/topic-architecture work +``` + +## Resume Protocol + +At the start of any resumed run: + +1. Read the execution board. +2. Run: + +```bash +python3 scripts/vision_exam_pipeline.py status --round round1 +``` + +3. Compare the status output against the board. +4. If they disagree, trust the files and fix the board. + +## Failure Handling + +If a worker stalls: + +- do not wait indefinitely +- reclaim the cluster and either narrow the task or do the integration locally + +If validation fails: + +- fix the failure before starting new cluster work + +If two clusters overlap unexpectedly: + +- pause parallel execution for those files +- assign one canonical owner + +## Minimum Overnight Deliverable + +A successful overnight run should ideally produce: + +- implemented high-value completeness improvements +- passing `make leave-better` +- an updated execution board +- a clear handoff about what is now ready for the next grading pass diff --git a/docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md b/docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md new file mode 100644 index 0000000..5139ea0 --- /dev/null +++ b/docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md @@ -0,0 +1,229 @@ +# Snippet Completeness Execution Checklist + +Execution-ready checklist for the current overnight objective: + +- maximize snippet completeness +- do not prematurely reorganize the UI or data architecture +- prepare the corpus for one more evidence-driven grading pass after the new snippets are in place + +This checklist is the primary execution surface for agents working on the post-synthesis snippet expansion round. + +## Objective + +Build the missing snippet corpus needed to answer past/mock exam questions more completely, while keeping the work: + +- cheat-sheet optimized +- concise +- selectable at the right granularity +- compatible with a later grading pass that will determine final topic/category structure + +## Current Scope Lock + +Do: + +- add the approved missing snippets +- expand or merge existing snippets where approved +- add metadata that may help later (`main_theme`, `related_themes`, `main_week`, `related_weeks`) if it is low-risk +- improve exact-match retrieval text only when it is clearly helpful and fair +- keep the corpus broad until the next grading pass + +Do not: + +- refactor the UI into topic-first navigation yet +- rewrite the overall topic/week data model yet +- hard-prune large parts of the corpus yet +- use OCR, `pdftotext`, or deterministic PDF text extraction for exam capture +- optimize rankings or categories based only on intuition + +## Sources Of Truth + +Start every run from these files: + +- [plan_after_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/plan_after_manual_synthesis.md) +- [round1_manual_synthesis.md](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/review_packets/round1_manual_synthesis.md) +- [exam_question_bank.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/exam_question_bank.json) +- [round1.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/vision_exam_pipeline/evaluations/round1.json) +- [topic_cards.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/topic_cards.json) +- [study_db.json](/Users/juliuseikmans/Desktop/Studies/2025-2026/intro%20to%20python/python-exam-cheat-sheet-generator/data/study_db.json) + +Quick state check: + +```bash +python3 scripts/vision_exam_pipeline.py status --round round1 +``` + +## Definition Of Done For This Phase + +This phase is done when: + +- all approved snippet additions/edits from the manual synthesis review are implemented +- the updated corpus remains internally valid +- no obvious high-value completeness gaps remain from the approved cluster list +- the project is ready for a fresh grading pass + +This phase is not done when: + +- the UI/topic architecture has been redesigned +- final ranking/preset logic has been implemented +- topic categories have been fully redefined + +## Execution Order + +### Phase 1. Prepare And Orient + +- [ ] Read the scope lock above. +- [ ] Run `python3 scripts/vision_exam_pipeline.py status --round round1`. +- [ ] Read the current plan and the manual synthesis packet. +- [ ] Identify the next highest-value unchecked cluster from the manual packet. +- [ ] Confirm whether the work is `add`, `edit existing`, or `merge into existing`. + +Done when: + +- you can state exactly which cluster you are working on +- you know which files you expect to touch + +### Phase 2. Implement High-Value Additions + +Start with these clusters: + +- [ ] Essential String Methods and Indexing Reference +- [ ] Output Formatting and String Construction +- [ ] Boolean String Predicates +- [ ] Iteration Helpers and Basic Operator Traps +- [ ] Comprehension Syntax Reference +- [ ] Dictionary Construction and Iteration Patterns +- [ ] Pandas Selection and Indexing Rules +- [ ] Lambda, `map`, and `apply` +- [ ] Datetime Parse/Format + object-vs-string arithmetic reference family +- [ ] OOP Fundamentals +- [ ] Flexible Arguments, Returns, and `kwargs` + +For each new snippet family: + +- [ ] prefer concise, exam-useful pieces +- [ ] include compact reference-first content +- [ ] add optional explanation only when it genuinely adds value +- [ ] split into separate selectable pieces only when users may reasonably want one without the other +- [ ] avoid turning one concept into many tiny fragments + +Done when: + +- the approved additions exist in the dataset +- they are selectable in a way that feels deliberate rather than over-fragmented + +### Phase 3. Implement Approved Expansions And Merges + +- [ ] Pandas Filtering, Aggregation, and Column Arithmetic: expand existing instead of blindly adding a new standalone cluster +- [ ] OOP Comparison Logic: merge into existing or expand the strongest current item +- [ ] Return-Value and Scope Cleanup: edit existing +- [ ] Exact-Match Retrieval Fixes: small, fair, non-biased improvements only + +Rules: + +- [ ] do not over-optimize `search_text` toward arbitrary snippets +- [ ] avoid making agents prefer one snippet only because its wording is easier to match +- [ ] preserve fair discoverability across similar snippets + +Done when: + +- existing high-value snippets are stronger, clearer, and more self-contained +- no retrieval improvement feels manipulative or unfair + +### Phase 4. Conservative Curation Pass + +- [ ] merge obvious near-duplicates +- [ ] avoid hard-pruning before the next grading pass unless something is clearly redundant or low quality +- [ ] preserve breadth of information +- [ ] prefer compact transformations over deletions when possible + +Done when: + +- the corpus is cleaner +- information breadth has not been meaningfully reduced + +### Phase 5. Validate + +- [ ] run targeted tests while working +- [ ] run `python3 scripts/vision_exam_pipeline.py status --round round1` again +- [ ] run `make leave-better` + +Done when: + +- tests pass +- maintenance audit has no failures + +### Phase 6. Prepare For The Next Pass + +- [ ] update the execution board +- [ ] write a concise handoff noting which clusters are complete, partially complete, or untouched +- [ ] note any unresolved ambiguity that should be reviewed before the next grading pass + +Done when: + +- another agent can resume work without reconstructing your reasoning from scratch + +## Snippet Design Rules + +### Piece Splitting + +Split into separate selectable pieces only when: + +- a user may want the compact version without the explanation +- a table and a code example can stand on their own +- one piece is clearly higher-value than the rest for space-constrained cheat sheets + +Keep bundled when: + +- the parts only make sense together +- splitting would create tiny low-value fragments +- the extra granularity would mostly add clutter + +### Two-Audience Rule + +Preferred pattern: + +- one compact reference piece +- one optional explanation piece + +Only provide both when they add genuinely different value. + +### Example Rules + +Good examples: + +- short correct syntax +- short incorrect syntax when it helps users spot traps +- slightly longer examples only when they efficiently teach several related patterns + +Avoid: + +- long decorative examples +- question-specific overfitting unless the same pattern recurs across multiple exams + +### Tables + +Use reference tables aggressively when they compress information better than prose. + +Good table types: + +- syntax / what it does +- correct / incorrect / why +- code / output +- operation / return type / common trap + +## Stop Conditions + +Stop and escalate if: + +- the work starts drifting into topic/UI restructuring +- you are about to delete a lot of existing content before the next grading pass +- two candidate snippets should maybe be one canonical snippet but the merge would destroy important nuance +- you are no longer improving completeness and are mostly bikeshedding presentation + +## Expected Next Phase After This One + +Do not do this yet, but optimize for it: + +- rerun question grading with the improved corpus +- record near-identical past exam pieces separately from the “best general snippet” judgments +- use actual co-usage patterns to inform future topic structure diff --git a/docs/specs/RM-009-vision-first-exam-curation-pipeline.md b/docs/specs/RM-009-vision-first-exam-curation-pipeline.md index c06e365..d242c33 100644 --- a/docs/specs/RM-009-vision-first-exam-curation-pipeline.md +++ b/docs/specs/RM-009-vision-first-exam-curation-pipeline.md @@ -3,10 +3,10 @@ ## Metadata - ID: `RM-009` -- Status: `planned` +- Status: `in_progress` - Priority: `High` - Owner: `codex/human` -- Last Updated: `2026-03-23` +- Last Updated: `2026-03-24` ## Problem @@ -66,6 +66,28 @@ Use the existing render packet pattern from `scripts/exam_coverage_audit.py` as - Reuse the existing rendered PNG packet when it matches the current source PDFs. - Review the question bank and evaluation summaries before implementing any snippet reclassification or UI changes. +## Current Follow-Up + +The pipeline itself is now in active use and has produced: + +- a complete canonical question bank +- a first completed evaluation round +- synthesis and analytics artifacts +- human/manual review packets + +The current follow-up phase is deliberately completeness-first: + +- improve the snippet corpus using the approved manual synthesis decisions +- avoid premature UI/topic-architecture refactors +- rerun grading only after the snippet corpus is stronger + +Operator docs for this follow-up live in: + +- `docs/curation/SNIPPET_COMPLETENESS_EXECUTION_CHECKLIST.md` +- `docs/curation/OVERNIGHT_AGENT_RUNBOOK.md` +- `docs/VISION_EXAM_PIPELINE.md` +- `data/vision_exam_pipeline/RUNBOOK.md` + ## Open Questions - Which exact JSON filenames should be treated as the long-term canonical review artifacts if the pipeline expands further? diff --git a/pipelines/vision_exam_pipeline.py b/pipelines/vision_exam_pipeline.py index 41b68ec..40353a6 100644 --- a/pipelines/vision_exam_pipeline.py +++ b/pipelines/vision_exam_pipeline.py @@ -26,6 +26,9 @@ write_evaluation_scaffold, write_ranking_analytics, ) +from pipelines.vision_exam_pipeline_status import ( + build_pipeline_status, +) from pipelines.vision_exam_pipeline_shared import ( ANALYTICS_DIR, COMPLETENESS_FILE, @@ -63,6 +66,7 @@ "auto_evaluate_questions", "build_completeness_report", "build_evaluation_scaffold", + "build_pipeline_status", "build_ranking_analytics", "build_review_packet", "build_selectable_items_snapshot", diff --git a/pipelines/vision_exam_pipeline_status.py b/pipelines/vision_exam_pipeline_status.py new file mode 100644 index 0000000..4b63908 --- /dev/null +++ b/pipelines/vision_exam_pipeline_status.py @@ -0,0 +1,123 @@ +from __future__ import annotations + +from collections import Counter +from pathlib import Path +from typing import Any + +from pipelines.vision_exam_pipeline_shared import ( + ANALYTICS_DIR, + COMPLETENESS_FILE, + EVALUATIONS_DIR, + QUESTION_BANK_FILE, + REVIEW_PACKET_DIR, + SYNTHESIS_DIR, + _read_json, + _safe_dict, + _safe_list, + _safe_str, + portable_path, + timestamp_utc, +) + + +def _existing_json(path: Path) -> dict[str, Any]: + if not path.exists(): + return {} + payload = _read_json(path) + return payload if isinstance(payload, dict) else {} + + +def _round_file(directory: Path, round_name: str, suffix: str = ".json") -> Path: + return directory / f"{round_name}{suffix}" + + +def build_pipeline_status(*, round_name: str = "round1") -> dict[str, Any]: + question_bank = _existing_json(QUESTION_BANK_FILE) + completeness = _existing_json(COMPLETENESS_FILE) + evaluations = _existing_json(_round_file(EVALUATIONS_DIR, round_name)) + synthesis = _existing_json(_round_file(SYNTHESIS_DIR, round_name)) + analytics = _existing_json(_round_file(ANALYTICS_DIR, round_name)) + review_packet = _existing_json(_round_file(REVIEW_PACKET_DIR, round_name)) + + exams = _safe_list(question_bank.get("exams")) + questions = [ + question + for exam in exams + for question in _safe_list(_safe_dict(exam).get("questions")) + if isinstance(question, dict) + ] + blocked = [ + question + for exam in exams + for question in _safe_list(_safe_dict(exam).get("blocked_questions")) + if isinstance(question, dict) + ] + review_status_counts = Counter( + _safe_str(_safe_dict(question.get("provenance")).get("review_status")) + for question in questions + if _safe_str(_safe_dict(question.get("provenance")).get("review_status")) + ) + + evaluation_questions = _safe_list(evaluations.get("questions")) + evaluation_status_counts = Counter( + _safe_str(_safe_dict(question).get("status")) + for question in evaluation_questions + if _safe_str(_safe_dict(question).get("status")) + ) + answerability_counts = Counter( + _safe_str(_safe_dict(_safe_dict(question).get("answerability")).get("status")) + for question in evaluation_questions + if _safe_str(_safe_dict(question).get("status")) == "completed" + ) + + overall_status = { + "question_bank_complete": _safe_str(completeness.get("overall_status")) == "complete", + "evaluation_round_complete": bool(evaluation_questions) + and evaluation_status_counts.get("completed", 0) == len(evaluation_questions), + "synthesis_exists": bool(synthesis), + "analytics_exists": bool(analytics), + "review_packet_exists": bool(review_packet), + } + if overall_status["evaluation_round_complete"] and overall_status["synthesis_exists"]: + next_gate = "human_review_of_synthesized_changes" + elif overall_status["question_bank_complete"]: + next_gate = "finish_or_refresh_question_to_snippet_evaluations" + else: + next_gate = "complete_question_bank_capture" + + return { + "generated_at": timestamp_utc(), + "round": round_name, + "paths": { + "question_bank": portable_path(QUESTION_BANK_FILE), + "completeness": portable_path(COMPLETENESS_FILE), + "evaluations": portable_path(_round_file(EVALUATIONS_DIR, round_name)), + "synthesis": portable_path(_round_file(SYNTHESIS_DIR, round_name)), + "analytics": portable_path(_round_file(ANALYTICS_DIR, round_name)), + "review_packet": portable_path(_round_file(REVIEW_PACKET_DIR, round_name)), + "manual_review_packet": portable_path(REVIEW_PACKET_DIR / f"{round_name}_manual_synthesis.md"), + }, + "question_bank": { + "canonical_exam_count": int(question_bank.get("canonical_exam_count") or 0), + "present_questions": len(questions), + "blocked_questions": len(blocked), + "review_status_counts": dict(review_status_counts), + "completeness_status": _safe_str(completeness.get("overall_status")) or "unknown", + }, + "evaluation_round": { + "exists": bool(evaluations), + "question_count": len(evaluation_questions), + "status_counts": dict(evaluation_status_counts), + "completed_evaluations": int(evaluation_status_counts.get("completed", 0)), + "answerability_counts": dict(answerability_counts), + }, + "review_outputs": { + "synthesis_exists": bool(synthesis), + "suggestion_count": int(_safe_dict(synthesis.get("summary")).get("suggestion_count") or 0), + "analytics_exists": bool(analytics), + "review_packet_exists": bool(review_packet), + "manual_review_packet_exists": (REVIEW_PACKET_DIR / f"{round_name}_manual_synthesis.md").exists(), + }, + "overall_status": overall_status, + "next_gate": next_gate, + } diff --git a/scripts/vision_exam_pipeline.py b/scripts/vision_exam_pipeline.py index 8a8341a..d3c350b 100644 --- a/scripts/vision_exam_pipeline.py +++ b/scripts/vision_exam_pipeline.py @@ -22,6 +22,7 @@ TMP_ROOT, auto_capture_missing_questions, auto_evaluate_questions, + build_pipeline_status, build_selectable_items_snapshot, merge_review_drop, prepare_page_manifest, @@ -100,6 +101,9 @@ def _parse_args() -> argparse.Namespace: review_packet.add_argument("--round", required=True) review_packet.add_argument("--selectable-items-path", type=Path, default=SELECTABLE_ITEMS_FILE) + status = subparsers.add_parser("status", help="Summarize the current pipeline state for one evaluation round.") + status.add_argument("--round", default="round1") + validate = subparsers.add_parser("validate", help="Validate question-bank and evaluation snippet references.") validate.add_argument("--evaluation-round", default="", help="Optional evaluation round to validate.") validate.add_argument("--question-bank-path", type=Path, default=QUESTION_BANK_FILE) @@ -207,6 +211,10 @@ def main() -> int: print(json.dumps({"review_packet_path": str(ROOT / "data" / "vision_exam_pipeline" / "review_packets" / f"{args.round}.md"), "theme_count": payload["summary"]["theme_count"]})) return 0 + if args.command == "status": + print(json.dumps(build_pipeline_status(round_name=args.round), ensure_ascii=False, indent=2)) + return 0 + errors = validate_all( question_bank_path=args.question_bank_path, selectable_items_path=args.selectable_items_path, diff --git a/tests/test_vision_exam_pipeline.py b/tests/test_vision_exam_pipeline.py index 59b7605..b0856a7 100644 --- a/tests/test_vision_exam_pipeline.py +++ b/tests/test_vision_exam_pipeline.py @@ -269,91 +269,6 @@ def test_build_ranking_analytics_tracks_week_counts_and_comparison(self) -> None self.assertEqual(1, analytics["comparison"]["fully_answerable"]["delta"]) self.assertIn("Week Summary", markdown) - def test_build_review_packet_surfaces_themes_and_top_snippets(self) -> None: - synthesis_payload = { - "suggestions": [ - { - "suggestion_id": "round1:1", - "proposal": "Add a snippet explaining string slicing and split().", - "pros": ["Helps with string parsing questions."], - "cons": [], - "recommended_direction": "add_this", - "source_exams": ["exam-a"], - }, - { - "suggestion_id": "round1:2", - "proposal": "Create a datetime cheat-sheet snippet using strptime and timedelta.", - "pros": ["Reduces guessing on datetime questions."], - "cons": [], - "recommended_direction": "add_this", - "source_exams": ["exam-b"], - }, - ] - } - analytics_payload = { - "weeks": [ - { - "week": 4, - "top1_unique_snippets": 2, - "top3_unique_snippets": 4, - "minimal_set_unique_snippets": 3, - "minimal_set_unused_snippets": 1, - } - ] - } - evaluation_payload = { - "questions": [ - { - "question_id": "q1", - "exam_id": "exam-a", - "status": "completed", - "answerability": {"status": "partial"}, - "gap_analysis": { - "summary": "Student needs string indexing and split rules.", - "missing_concepts": ["string slicing"], - "proposed_fix": "Add a string methods summary snippet.", - }, - "best_single_snippet": {"item_id": "snippet-1"}, - "top_three_snippets": [{"item_id": "snippet-1"}], - "minimal_sufficient_snippets": [{"item_id": "snippet-1"}], - }, - { - "question_id": "q2", - "exam_id": "exam-b", - "status": "completed", - "answerability": {"status": "insufficient"}, - "gap_analysis": { - "summary": "Student lacks datetime parsing rules.", - "missing_concepts": ["datetime.strptime"], - "proposed_fix": "Add a datetime and timedelta summary card.", - }, - "best_single_snippet": {"item_id": "snippet-2"}, - "top_three_snippets": [{"item_id": "snippet-2"}], - "minimal_sufficient_snippets": [{"item_id": "snippet-2"}], - }, - ] - } - selectable_items = [ - {"item_id": "snippet-1", "week": 4, "topic": "Strings", "bucket": "recommended", "item_type": "source_exam", "search_text": "String slicing and split example."}, - {"item_id": "snippet-2", "week": 6, "topic": "Datetime", "bucket": "recommended", "item_type": "source_exam", "search_text": "Datetime parsing example."}, - ] - - packet, markdown = pipeline.build_review_packet( - round_name="round1", - synthesis_payload=synthesis_payload, - analytics_payload=analytics_payload, - evaluation_payload=evaluation_payload, - selectable_items=selectable_items, - ) - - self.assertEqual(2, packet["summary"]["completed_evaluations"]) - theme_names = {theme["theme_name"] for theme in packet["themes"]} - self.assertIn("Strings, Indexing, and Text Methods", theme_names) - self.assertIn("Datetime and Timedelta", theme_names) - self.assertTrue(packet["top_existing_snippets"]) - self.assertIn("Recommended Review Order", markdown) - self.assertIn("Strong Existing Snippets", markdown) - def test_validate_question_bank_payload_requires_reasoned_blocked_slots(self) -> None: errors = pipeline.validate_question_bank_payload( { diff --git a/tests/test_vision_exam_pipeline_followup.py b/tests/test_vision_exam_pipeline_followup.py new file mode 100644 index 0000000..21dd784 --- /dev/null +++ b/tests/test_vision_exam_pipeline_followup.py @@ -0,0 +1,169 @@ +from __future__ import annotations + +import json +from pathlib import Path +import tempfile +import unittest +from unittest import mock + +from pipelines import vision_exam_pipeline as pipeline +from pipelines import vision_exam_pipeline_status as pipeline_status + + +class VisionExamPipelineFollowupTests(unittest.TestCase): + def test_build_review_packet_surfaces_themes_and_top_snippets(self) -> None: + synthesis_payload = { + "suggestions": [ + { + "suggestion_id": "round1:1", + "proposal": "Add a snippet explaining string slicing and split().", + "pros": ["Helps with string parsing questions."], + "cons": [], + "recommended_direction": "add_this", + "source_exams": ["exam-a"], + }, + { + "suggestion_id": "round1:2", + "proposal": "Create a datetime cheat-sheet snippet using strptime and timedelta.", + "pros": ["Reduces guessing on datetime questions."], + "cons": [], + "recommended_direction": "add_this", + "source_exams": ["exam-b"], + }, + ] + } + analytics_payload = { + "weeks": [ + { + "week": 4, + "top1_unique_snippets": 2, + "top3_unique_snippets": 4, + "minimal_set_unique_snippets": 3, + "minimal_set_unused_snippets": 1, + } + ] + } + evaluation_payload = { + "questions": [ + { + "question_id": "q1", + "exam_id": "exam-a", + "status": "completed", + "answerability": {"status": "partial"}, + "gap_analysis": { + "summary": "Student needs string indexing and split rules.", + "missing_concepts": ["string slicing"], + "proposed_fix": "Add a string methods summary snippet.", + }, + "best_single_snippet": {"item_id": "snippet-1"}, + "top_three_snippets": [{"item_id": "snippet-1"}], + "minimal_sufficient_snippets": [{"item_id": "snippet-1"}], + }, + { + "question_id": "q2", + "exam_id": "exam-b", + "status": "completed", + "answerability": {"status": "insufficient"}, + "gap_analysis": { + "summary": "Student lacks datetime parsing rules.", + "missing_concepts": ["datetime.strptime"], + "proposed_fix": "Add a datetime and timedelta summary card.", + }, + "best_single_snippet": {"item_id": "snippet-2"}, + "top_three_snippets": [{"item_id": "snippet-2"}], + "minimal_sufficient_snippets": [{"item_id": "snippet-2"}], + }, + ] + } + selectable_items = [ + {"item_id": "snippet-1", "week": 4, "topic": "Strings", "bucket": "recommended", "item_type": "source_exam", "search_text": "String slicing and split example."}, + {"item_id": "snippet-2", "week": 6, "topic": "Datetime", "bucket": "recommended", "item_type": "source_exam", "search_text": "Datetime parsing example."}, + ] + + packet, markdown = pipeline.build_review_packet( + round_name="round1", + synthesis_payload=synthesis_payload, + analytics_payload=analytics_payload, + evaluation_payload=evaluation_payload, + selectable_items=selectable_items, + ) + + self.assertEqual(2, packet["summary"]["completed_evaluations"]) + theme_names = {theme["theme_name"] for theme in packet["themes"]} + self.assertIn("Strings, Indexing, and Text Methods", theme_names) + self.assertIn("Datetime and Timedelta", theme_names) + self.assertTrue(packet["top_existing_snippets"]) + self.assertIn("Recommended Review Order", markdown) + self.assertIn("Strong Existing Snippets", markdown) + + def test_build_pipeline_status_summarizes_current_artifacts(self) -> None: + with tempfile.TemporaryDirectory() as tmp: + tmp_root = Path(tmp) + question_bank_path = tmp_root / "exam_question_bank.json" + completeness_path = tmp_root / "exam_question_bank_completeness.json" + evaluations_dir = tmp_root / "evaluations" + synthesis_dir = tmp_root / "synthesis" + analytics_dir = tmp_root / "analytics" + review_packets_dir = tmp_root / "review_packets" + + question_bank_path.write_text( + json.dumps( + { + "canonical_exam_count": 1, + "exams": [ + { + "exam_id": "demo-exam", + "questions": [ + { + "question_id": "demo-exam-q01", + "number": 1, + "provenance": {"review_status": "agent_reviewed_pending_human_confirmation"}, + } + ], + "blocked_questions": [], + } + ], + } + ), + encoding="utf-8", + ) + completeness_path.write_text(json.dumps({"overall_status": "complete"}), encoding="utf-8") + evaluations_dir.mkdir() + synthesis_dir.mkdir() + analytics_dir.mkdir() + review_packets_dir.mkdir() + (evaluations_dir / "round1.json").write_text( + json.dumps( + { + "questions": [ + { + "question_id": "demo-exam-q01", + "status": "completed", + "answerability": {"status": "certain"}, + } + ] + } + ), + encoding="utf-8", + ) + (synthesis_dir / "round1.json").write_text(json.dumps({"summary": {"suggestion_count": 3}}), encoding="utf-8") + (analytics_dir / "round1.json").write_text(json.dumps({"summary": {"completed_evaluations": 1}}), encoding="utf-8") + (review_packets_dir / "round1.json").write_text(json.dumps({"summary": {"theme_count": 2}}), encoding="utf-8") + (review_packets_dir / "round1_manual_synthesis.md").write_text("# manual\n", encoding="utf-8") + + with mock.patch.object(pipeline_status, "QUESTION_BANK_FILE", question_bank_path), \ + mock.patch.object(pipeline_status, "COMPLETENESS_FILE", completeness_path), \ + mock.patch.object(pipeline_status, "EVALUATIONS_DIR", evaluations_dir), \ + mock.patch.object(pipeline_status, "SYNTHESIS_DIR", synthesis_dir), \ + mock.patch.object(pipeline_status, "ANALYTICS_DIR", analytics_dir), \ + mock.patch.object(pipeline_status, "REVIEW_PACKET_DIR", review_packets_dir): + status = pipeline.build_pipeline_status(round_name="round1") + + self.assertEqual("complete", status["question_bank"]["completeness_status"]) + self.assertEqual(1, status["evaluation_round"]["completed_evaluations"]) + self.assertEqual("human_review_of_synthesized_changes", status["next_gate"]) + self.assertTrue(status["review_outputs"]["manual_review_packet_exists"]) + + +if __name__ == "__main__": + unittest.main() From 2f23817652947cb65cef7e929c40774f005531ca Mon Sep 17 00:00:00 2001 From: caspersimon <165684406+caspersimon@users.noreply.github.com> Date: Tue, 24 Mar 2026 19:11:48 +0100 Subject: [PATCH 4/6] Rebuild exam-first cheat sheet pipeline and manually curate topics --- .DS_Store | Bin 14340 -> 14340 bytes app/card-interactions.js | 232 +- app/exam-builder-data.js | 200 + app/preview-card-render.js | 323 +- app/preview-editing.js | 544 +- app/preview-render.js | 153 +- app/render-card-sections.js | 537 +- app/splash-storage.js | 74 +- app/state-and-init.js | 64 +- app/topic-selection.js | 452 +- app/view-and-data.js | 203 +- data/exam_builder_topics.json | 7975 ++ .../collections_and_iteration.json | 870 + .../datetime_and_oop.json | 1083 + .../functions_and_program_flow.json | 540 + .../pandas_data_work.json | 509 + .../python_foundations.json | 1058 + .../strings_and_output.json | 409 + .../OVERNIGHT_EXECUTION_BOARD.md | 92 +- .../analytics/round2.json | 528 + data/vision_exam_pipeline/analytics/round2.md | 22 + .../evaluations/round2.json | 61345 ++++++++++++++++ .../round2_partial_and_insufficient.md | 6635 ++ .../selectable_snippet_catalog.md | 5912 ++ .../selectable_items_snapshot.json | 3766 +- ...utions-for-python-programming-62oop21.json | 8888 +++ ...-study-guide-trial-python-basics-2023.json | 8848 +++ ...ython-trial-final-exam-solutions-py22.json | 8702 +++ ...-intro-to-python-6013b0470y-july-2023.json | 8844 +++ ...s-for-introduction-to-python-35761538.json | 8806 +++ .../round2/sample-final-plus-answers.json | 8702 +++ ...utions-introduction-to-python-3077951.json | 8630 +++ .../HOURLY_ORCHESTRATOR_SUPERVISOR_PROMPT.txt | 61 + docs/curation/OVERNIGHT_AGENT_RUNBOOK.md | 33 + docs/curation/OVERNIGHT_SUPERVISOR_PROMPT.md | 64 + docs/curation/OVERNIGHT_SUPERVISOR_PROMPT.txt | 54 + docs/curation/OVERNIGHT_WORKER_PROMPTS.md | 68 + index.html | 54 +- pipelines/exam_builder_dataset.py | 220 + pipelines/exam_builder_dataset_families.py | 245 + pipelines/exam_builder_dataset_specs.py | 108 + pipelines/exam_builder_manual_snippets.py | 9 + .../exam_builder_manual_snippets_part1.py | 265 + .../exam_builder_manual_snippets_part2.py | 280 + pipelines/vision_exam_pipeline.py | 10 +- pipelines/vision_exam_pipeline_analytics.py | 209 + pipelines/vision_exam_pipeline_batch.py | 26 + .../vision_exam_pipeline_eval_helpers.py | 241 + pipelines/vision_exam_pipeline_gemini.py | 219 +- pipelines/vision_exam_pipeline_review.py | 204 +- pipelines/vision_exam_pipeline_selectable.py | 60 + pipelines/vision_exam_pipeline_shared.py | 16 +- scripts/build_exam_builder_dataset.py | 21 + scripts/build_manual_exam_builder_dataset.py | 438 + scripts/export_round_gap_report.py | 225 + scripts/export_selectable_snippet_catalog.py | 149 + scripts/hourly_supervisor_watch.py | 174 + scripts/hourly_supervisor_watch_manager.py | 181 + scripts/overnight_loop_status.sh | 35 + scripts/overnight_snippet_loop.py | 167 + scripts/round2_grading_status.sh | 37 + scripts/run_evaluation_batches.py | 105 + scripts/start_overnight_snippet_loop.sh | 24 + scripts/start_round2_grading.sh | 28 + scripts/stop_overnight_snippet_loop.sh | 16 + scripts/stop_round2_grading.sh | 10 + scripts/supervise_round2_grading.py | 165 + styles.css | 1 + styles/09-exam-builder.css | 71 + tests/test_exam_builder_dataset.py | 75 + tests/test_hourly_supervisor_watch.py | 66 + tests/test_vision_exam_pipeline_batch.py | 39 + .../launchd.stderr.log | 18 + .../launchd.stdout.log | 0 .../hourly_supervisor_watch/launcher.log | 26 + .../run-20260324-021038/events.jsonl | 0 .../run-20260324-021038/stderr.log | 0 .../run-20260324-021148/events.jsonl | 24 + .../run-20260324-021148/stderr.log | 0 .../run-20260324-021301/events.jsonl | 4 + .../run-20260324-021301/last_message.txt | 7 + .../run-20260324-021301/stderr.log | 0 .../run-20260324-031330/events.jsonl | 11 + .../run-20260324-031330/last_message.txt | 7 + .../run-20260324-031330/stderr.log | 0 .../run-20260324-041356/events.jsonl | 4 + .../run-20260324-041356/last_message.txt | 7 + .../run-20260324-041356/stderr.log | 0 .../run-20260324-051412/events.jsonl | 4 + .../run-20260324-051412/last_message.txt | 7 + .../run-20260324-051412/stderr.log | 0 .../run-20260324-061424/events.jsonl | 4 + .../run-20260324-061424/last_message.txt | 7 + .../run-20260324-061424/stderr.log | 0 .../run-20260324-071436/events.jsonl | 4 + .../run-20260324-071436/last_message.txt | 7 + .../run-20260324-071436/stderr.log | 0 .../run-20260324-081456/events.jsonl | 4 + .../run-20260324-081456/last_message.txt | 7 + .../run-20260324-081456/stderr.log | 0 .../hourly_supervisor_watch/state.json | 7 + tmp/vision_exam_pipeline/overnight_loop/STOP | 1 + .../overnight_loop/iteration-001/events.jsonl | 261 + .../iteration-001/last_message.txt | 5 + .../overnight_loop/iteration-001/stderr.log | 103 + .../overnight_loop/iteration-002/events.jsonl | 266 + .../iteration-002/last_message.txt | 3 + .../overnight_loop/iteration-002/stderr.log | 99 + .../overnight_loop/launcher.log | 9 + .../overnight_loop/state.json | 110 + .../round2_grading/analytics.exit | 1 + .../round2_grading/analytics.log | 1 + .../round2_grading/auto_evaluate.exit | 1 + .../round2_grading/auto_evaluate.log | 0 .../round2_grading/runner.sh | 6 + .../round2_grading/supervisor.jsonl | 127 + .../round2_grading/supervisor_state.json | 10 + .../round2_grading/validate.exit | 1 + .../round2_grading/validate.log | 1 + topic_cards.json | 1782 +- 120 files changed, 159090 insertions(+), 3275 deletions(-) create mode 100644 app/exam-builder-data.js create mode 100644 data/exam_builder_topics.json create mode 100644 data/manual_curation_drafts/collections_and_iteration.json create mode 100644 data/manual_curation_drafts/datetime_and_oop.json create mode 100644 data/manual_curation_drafts/functions_and_program_flow.json create mode 100644 data/manual_curation_drafts/pandas_data_work.json create mode 100644 data/manual_curation_drafts/python_foundations.json create mode 100644 data/manual_curation_drafts/strings_and_output.json create mode 100644 data/vision_exam_pipeline/analytics/round2.json create mode 100644 data/vision_exam_pipeline/analytics/round2.md create mode 100644 data/vision_exam_pipeline/evaluations/round2.json create mode 100644 data/vision_exam_pipeline/review_packets/round2_partial_and_insufficient.md create mode 100644 data/vision_exam_pipeline/review_packets/selectable_snippet_catalog.md create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-solutions-for-python-programming-62oop21.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-study-guide-trial-python-basics-2023.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round2/introduction-to-python-trial-final-exam-solutions-py22.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round2/resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round2/resit-solutions-for-introduction-to-python-35761538.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round2/sample-final-plus-answers.json create mode 100644 data/vision_exam_pipeline/work_packets/evaluations/round2/trial-final-exam-solutions-introduction-to-python-3077951.json create mode 100644 docs/curation/HOURLY_ORCHESTRATOR_SUPERVISOR_PROMPT.txt create mode 100644 docs/curation/OVERNIGHT_SUPERVISOR_PROMPT.md create mode 100644 docs/curation/OVERNIGHT_SUPERVISOR_PROMPT.txt create mode 100644 docs/curation/OVERNIGHT_WORKER_PROMPTS.md create mode 100644 pipelines/exam_builder_dataset.py create mode 100644 pipelines/exam_builder_dataset_families.py create mode 100644 pipelines/exam_builder_dataset_specs.py create mode 100644 pipelines/exam_builder_manual_snippets.py create mode 100644 pipelines/exam_builder_manual_snippets_part1.py create mode 100644 pipelines/exam_builder_manual_snippets_part2.py create mode 100644 pipelines/vision_exam_pipeline_analytics.py create mode 100644 pipelines/vision_exam_pipeline_batch.py create mode 100644 pipelines/vision_exam_pipeline_eval_helpers.py create mode 100644 pipelines/vision_exam_pipeline_selectable.py create mode 100644 scripts/build_exam_builder_dataset.py create mode 100644 scripts/build_manual_exam_builder_dataset.py create mode 100644 scripts/export_round_gap_report.py create mode 100644 scripts/export_selectable_snippet_catalog.py create mode 100644 scripts/hourly_supervisor_watch.py create mode 100644 scripts/hourly_supervisor_watch_manager.py create mode 100755 scripts/overnight_loop_status.sh create mode 100644 scripts/overnight_snippet_loop.py create mode 100755 scripts/round2_grading_status.sh create mode 100644 scripts/run_evaluation_batches.py create mode 100755 scripts/start_overnight_snippet_loop.sh create mode 100755 scripts/start_round2_grading.sh create mode 100755 scripts/stop_overnight_snippet_loop.sh create mode 100755 scripts/stop_round2_grading.sh create mode 100644 scripts/supervise_round2_grading.py create mode 100644 styles/09-exam-builder.css create mode 100644 tests/test_exam_builder_dataset.py create mode 100644 tests/test_hourly_supervisor_watch.py create mode 100644 tests/test_vision_exam_pipeline_batch.py create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/launchd.stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/launchd.stdout.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/launcher.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-021038/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-021038/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-021148/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-021148/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-021301/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-021301/last_message.txt create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-021301/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-031330/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-031330/last_message.txt create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-031330/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-041356/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-041356/last_message.txt create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-041356/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-051412/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-051412/last_message.txt create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-051412/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-061424/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-061424/last_message.txt create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-061424/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-071436/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-071436/last_message.txt create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-071436/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-081456/events.jsonl create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-081456/last_message.txt create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/run-20260324-081456/stderr.log create mode 100644 tmp/vision_exam_pipeline/hourly_supervisor_watch/state.json create mode 100644 tmp/vision_exam_pipeline/overnight_loop/STOP create mode 100644 tmp/vision_exam_pipeline/overnight_loop/iteration-001/events.jsonl create mode 100644 tmp/vision_exam_pipeline/overnight_loop/iteration-001/last_message.txt create mode 100644 tmp/vision_exam_pipeline/overnight_loop/iteration-001/stderr.log create mode 100644 tmp/vision_exam_pipeline/overnight_loop/iteration-002/events.jsonl create mode 100644 tmp/vision_exam_pipeline/overnight_loop/iteration-002/last_message.txt create mode 100644 tmp/vision_exam_pipeline/overnight_loop/iteration-002/stderr.log create mode 100644 tmp/vision_exam_pipeline/overnight_loop/launcher.log create mode 100644 tmp/vision_exam_pipeline/overnight_loop/state.json create mode 100644 tmp/vision_exam_pipeline/round2_grading/analytics.exit create mode 100644 tmp/vision_exam_pipeline/round2_grading/analytics.log create mode 100644 tmp/vision_exam_pipeline/round2_grading/auto_evaluate.exit create mode 100644 tmp/vision_exam_pipeline/round2_grading/auto_evaluate.log create mode 100755 tmp/vision_exam_pipeline/round2_grading/runner.sh create mode 100644 tmp/vision_exam_pipeline/round2_grading/supervisor.jsonl create mode 100644 tmp/vision_exam_pipeline/round2_grading/supervisor_state.json create mode 100644 tmp/vision_exam_pipeline/round2_grading/validate.exit create mode 100644 tmp/vision_exam_pipeline/round2_grading/validate.log diff --git a/.DS_Store b/.DS_Store index daa4ad802150db6f221723fccabd955fb7c321de..117923874b87999d49c49ca77004dc79825c209c 100644 GIT binary patch delta 849 zcmZoEXepQ=#l*xpQN~y_je&uInSnuofgzcpI5WAdASow5Y2(GkjFSyaSSEH0Zsynf z!MO3kXXef994s7+CKG`=Z%&xZBOt+6w%qmy=g!Gm0#Y!hmw*i8fz9ax)?CaI>Psgl zNQq6}EycsJHsztF+s@;TAOVrw{1g|E9YA|gBqsAq^D@aLOqP?L&CIu7Z}J{#Ikw9T znI{u>PJSS*fMAMDmXhIR5_H(CDHF%Y%sx+ka+jY`h zA%`K6p^~ATp$KSAIzt9S34<;$?s6D1bJ7uxV_*uN1auAo9mtM+AabL7+IDbI;Lzm@ zvj{l~32TGtLiP~@Q^RC#CF#v)6^j^|mX}X8BQcbT$tRbBFze6EmVQ*D`J<}L<~u4{oExtiGEQbU5N2cIWMEL>*?93i l^JIP#T@g@>F#>S|ga$DgCWn};oXn^qHrZZ9iF`XFm;i6w?a}}M delta 677 zcmZoEXepQ=#l+AyQN~y_iGhKEnSnuofgzcpI49jOI5|JJU}B;2WCIhH$=pnWlO+WB zn5-vH)=`kyd`ZugakBykJIiJT7Ivo1>>Ml{F~&gsEDR|O`5^td`7SO=Ir$(nIeuSA zcxAEUxFf233SRkw42b?C%EVxWVI7%~|O7)lt5Q7q;) z*z773$LPxXFdOI$R-k+;P&H5$viF>d<-&a+-a}D=a2Q0z>_rPUcgZy}PHd22)SJws5EjQ9*#t5X;ff$mR4wtBXi=TD2tfvVE15LTh840C7!!{mc%GMm?^YH@BB zW@2QT%x)me#sGA_0?%eamiNq)`Au{=8G%L~0Ahy8HayakV@&2wZWM~&tfRJq2>`CG Bz9;|y diff --git a/app/card-interactions.js b/app/card-interactions.js index 994bfef..db4fcdc 100644 --- a/app/card-interactions.js +++ b/app/card-interactions.js @@ -9,78 +9,45 @@ function getCardById(cardId) { function handleCardInputChange(event) { const input = event.target; const role = input.dataset.role; - const cardId = input.dataset.cardId || ""; - const card = cardId ? getCardById(cardId) : null; + if (role !== "item-toggle") { + return; + } + const card = getCardById(input.dataset.cardId || ""); if (!card) { return; } const draft = ensureDraft(card); - const section = input.dataset.section || ""; - - if (role === "section-toggle") { - draft.sections[section] = Boolean(input.checked); - renderAll(); + const pieceId = input.dataset.pieceId || ""; + if (!pieceId) { return; } - if (role === "item-toggle") { - const itemId = input.dataset.itemId || ""; - const key = sectionToSelectionKey(section); - if (!key || !itemId) { - return; - } - - const next = new Set(draft.selected[key] || []); - if (input.checked) { - next.add(itemId); - draft.sections[section] = true; - } else { - next.delete(itemId); - } - draft.selected[key] = [...next]; - renderAll(); + const next = new Set(draft.selected.pieces || []); + if (input.checked) { + next.add(pieceId); + } else { + next.delete(pieceId); } + draft.selected.pieces = [...next]; + renderAll(); } function handleCardClick(event) { - const infoTrigger = event.target.closest("[data-role='toggle-info']"); - if (infoTrigger) { - event.preventDefault(); - const infoChip = infoTrigger.closest(".info-chip"); - if (!infoChip) { - return; - } - const shouldOpen = !infoChip.classList.contains("open"); - closeOpenInfoPopovers(); - if (shouldOpen) { - infoChip.classList.add("open"); - positionInfoPopover(infoChip); - } - return; - } - const openTopicTrigger = event.target.closest("[data-role='open-topic']"); if (openTopicTrigger) { event.preventDefault(); - const cardId = openTopicTrigger.dataset.cardId || ""; - const week = Number(openTopicTrigger.dataset.week || 0); - setActiveTopic(cardId, week); + setActiveTopic(openTopicTrigger.dataset.cardId || "", openTopicTrigger.dataset.parentId || ""); closeTopicSidebar(); renderAll(); return; } - const toggleWeekTrigger = event.target.closest("[data-role='toggle-week']"); - if (toggleWeekTrigger) { + const toggleParentTrigger = event.target.closest("[data-role='toggle-parent']"); + if (toggleParentTrigger) { event.preventDefault(); - const week = Number(toggleWeekTrigger.dataset.week || 0); - if (Number.isFinite(week) && week > 0) { - toggleWeekExpanded(week); - renderSwipe(); - schedulePersistState(); - } + toggleParentExpanded(toggleParentTrigger.dataset.parentId || ""); return; } @@ -93,21 +60,38 @@ function handleCardClick(event) { return; } - const sectionSelectAllTrigger = event.target.closest("[data-role='select-all-section']"); - if (sectionSelectAllTrigger) { + const selectAllSectionTrigger = event.target.closest("[data-role='select-all-section']"); + if (selectAllSectionTrigger) { event.preventDefault(); - const cardId = sectionSelectAllTrigger.dataset.cardId || ""; - const section = sectionSelectAllTrigger.dataset.section || ""; - selectAllSectionItems(cardId, section); + selectAllSectionPieces(selectAllSectionTrigger.dataset.cardId || "", selectAllSectionTrigger.dataset.sectionKey || ""); return; } const clearSectionTrigger = event.target.closest("[data-role='clear-section']"); if (clearSectionTrigger) { event.preventDefault(); - const cardId = clearSectionTrigger.dataset.cardId || ""; - const section = clearSectionTrigger.dataset.section || ""; - clearSectionItems(cardId, section); + clearSectionPieces(clearSectionTrigger.dataset.cardId || "", clearSectionTrigger.dataset.sectionKey || ""); + return; + } + + const selectAllSnippetTrigger = event.target.closest("[data-role='select-all-snippet']"); + if (selectAllSnippetTrigger) { + event.preventDefault(); + selectAllSnippetPieces(selectAllSnippetTrigger.dataset.cardId || "", selectAllSnippetTrigger.dataset.snippetId || ""); + return; + } + + const clearSnippetTrigger = event.target.closest("[data-role='clear-snippet']"); + if (clearSnippetTrigger) { + event.preventDefault(); + clearSnippetPieces(clearSnippetTrigger.dataset.cardId || "", clearSnippetTrigger.dataset.snippetId || ""); + return; + } + + const toggleSectionExpandedTrigger = event.target.closest("[data-role='toggle-section-expanded']"); + if (toggleSectionExpandedTrigger) { + event.preventDefault(); + toggleSectionExpanded(toggleSectionExpandedTrigger.dataset.cardId || "", toggleSectionExpandedTrigger.dataset.sectionKey || ""); return; } @@ -122,126 +106,74 @@ function handleCardClick(event) { if (resetProgressTrigger) { event.preventDefault(); resetAppProgress(); - return; - } - - if (!event.target.closest(".info-chip")) { - closeOpenInfoPopovers(); } } -function handleCardMouseOver(event) { - const infoChip = event.target.closest(".info-chip"); - if (!infoChip || !refs.cardHost.contains(infoChip)) { - return; - } - positionInfoPopover(infoChip); -} +function handleCardMouseOver(_event) {} -function selectAllSectionItems(cardId, section) { +function selectAllSectionPieces(cardId, sectionKey) { const card = getCardById(cardId); if (!card) { return; } const draft = ensureDraft(card); - const key = sectionToSelectionKey(section); - if (!key) { - return; - } - - const allIds = getSectionSelectableIds(card, section); - draft.sections[section] = true; - draft.selected[key] = [...new Set(allIds)]; + draft.selected.pieces = [...new Set([...(draft.selected.pieces || []), ...getSectionSelectablePieceIds(card, sectionKey)])]; renderAll(); } -function clearSectionItems(cardId, section) { +function clearSectionPieces(cardId, sectionKey) { const card = getCardById(cardId); if (!card) { return; } const draft = ensureDraft(card); - const key = sectionToSelectionKey(section); - if (!key) { - return; - } - - draft.selected[key] = []; - if (key === "keyPoints") { - const overrides = draft.overrides || {}; - overrides.keyPoints = {}; - overrides.keyPointDetails = {}; - draft.overrides = overrides; - } else if (key === "aiExamples") { - draft.overrides.aiExamples = {}; - } else { - draft.overrides.sources = {}; - } + const removeIds = new Set(getSectionSelectablePieceIds(card, sectionKey)); + draft.selected.pieces = (draft.selected.pieces || []).filter((pieceId) => !removeIds.has(pieceId)); + const overrides = ensureSelectionOverrides(draft); + Object.keys(overrides.pieces).forEach((pieceId) => { + if (removeIds.has(pieceId)) { + delete overrides.pieces[pieceId]; + } + }); renderAll(); } -function getSectionSelectableIds(card, section) { - if (section === "aiQuestions") { - return commonQuestionSelectableIds(card); - } - if (section === "keyPoints") { - return keyPointSelectableIds(card); - } - if (section === "aiExamples") { - return usefulAIExamples(card).map((item) => item.id); - } - if (section === "recommended" || section === "additional") { - return getSourceSplit(card)[section].map((item) => item.id); +function selectAllSnippetPieces(cardId, snippetId) { + const card = getCardById(cardId); + if (!card) { + return; } - return []; + const draft = ensureDraft(card); + draft.selected.pieces = [...new Set([...(draft.selected.pieces || []), ...getSnippetSelectablePieceIds(card, snippetId)])]; + renderAll(); } -function positionInfoPopover(infoChip) { - const popover = infoChip.querySelector(".info-popover"); - if (!popover) { +function clearSnippetPieces(cardId, snippetId) { + const card = getCardById(cardId); + if (!card) { return; } - - popover.style.setProperty("--popover-shift-x", "0px"); - popover.style.setProperty("--popover-shift-y", "0px"); - - window.requestAnimationFrame(() => { - const rect = popover.getBoundingClientRect(); - const viewportPadding = 8; - const maxRight = window.innerWidth - viewportPadding; - const maxBottom = window.innerHeight - viewportPadding; - let shiftX = 0; - let shiftY = 0; - - if (rect.left < viewportPadding) { - shiftX += viewportPadding - rect.left; - } - if (rect.right > maxRight) { - shiftX -= rect.right - maxRight; - } - if (rect.bottom > maxBottom) { - shiftY -= rect.bottom - maxBottom; - } - if (rect.top + shiftY < viewportPadding) { - shiftY += viewportPadding - (rect.top + shiftY); + const draft = ensureDraft(card); + const removeIds = new Set(getSnippetSelectablePieceIds(card, snippetId)); + draft.selected.pieces = (draft.selected.pieces || []).filter((pieceId) => !removeIds.has(pieceId)); + const overrides = ensureSelectionOverrides(draft); + Object.keys(overrides.pieces).forEach((pieceId) => { + if (removeIds.has(pieceId)) { + delete overrides.pieces[pieceId]; } - - popover.style.setProperty("--popover-shift-x", `${Math.round(shiftX)}px`); - popover.style.setProperty("--popover-shift-y", `${Math.round(shiftY)}px`); }); + renderAll(); } -function closeOpenInfoPopovers() { - refs.selectionShell?.querySelectorAll(".info-chip.open").forEach((chip) => chip.classList.remove("open")); +function toggleSectionExpanded(cardId, sectionKey) { + const card = getCardById(cardId); + if (!card) { + return; + } + const draft = ensureDraft(card); + draft.ui.expandedSections[sectionKey] = !Boolean(draft.ui.expandedSections[sectionKey]); + renderAll(); + schedulePersistState(); } -function sectionToSelectionKey(section) { - const map = { - aiQuestions: "aiQuestions", - aiExamples: "aiExamples", - keyPoints: "keyPoints", - recommended: "recommended", - additional: "additional", - }; - return map[section] || ""; -} +function closeOpenInfoPopovers() {} diff --git a/app/exam-builder-data.js b/app/exam-builder-data.js new file mode 100644 index 0000000..a8fea18 --- /dev/null +++ b/app/exam-builder-data.js @@ -0,0 +1,200 @@ +const EXAM_BUILDER_SECTION_LABELS = { + must_know: "Must Know", + exam_patterns: "Exam Patterns", + useful_backup: "Useful Backup", +}; + +const EXAM_BUILDER_SECTION_DESCRIPTIONS = { + must_know: "The fastest, densest references you should reach for first.", + exam_patterns: "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + useful_backup: "Support material to add when a narrower question still leaves a gap.", +}; + +function normalizeExamBuilderPayload(payload) { + const parentTopics = Array.isArray(payload?.parent_topics) + ? payload.parent_topics.map(normalizeExamParentTopic).filter(Boolean) + : []; + const cards = flattenExamBuilderTopics(parentTopics); + return { parentTopics, cards }; +} + +function normalizeExamParentTopic(parentTopic) { + if (!parentTopic || typeof parentTopic !== "object") { + return null; + } + + const mainTopics = Array.isArray(parentTopic.main_topics) + ? parentTopic.main_topics.map((topic) => normalizeExamCard(parentTopic, topic)).filter(Boolean) + : []; + + return { + id: String(parentTopic.id || "").trim(), + title: String(parentTopic.title || "Topic Group").trim(), + summary: String(parentTopic.summary || "").trim(), + mainTopics, + }; +} + +function flattenExamBuilderTopics(parentTopics) { + return parentTopics.flatMap((parentTopic) => parentTopic.mainTopics || []); +} + +function normalizeExamCard(parentTopic, mainTopic) { + if (!mainTopic || typeof mainTopic !== "object") { + return null; + } + + const mainWeek = Number(mainTopic.main_week || 0); + const relatedWeeks = Array.isArray(mainTopic.related_weeks) + ? mainTopic.related_weeks.map((value) => Number(value)).filter((value) => Number.isFinite(value) && value > 0) + : []; + const weeks = [...new Set([mainWeek, ...relatedWeeks].filter((value) => Number.isFinite(value) && value > 0))]; + const sections = Array.isArray(mainTopic.sections) + ? mainTopic.sections.map(normalizeExamSection).filter(Boolean) + : []; + + const allSnippets = sections.flatMap((section) => section.snippets); + const allPieces = allSnippets.flatMap((snippet) => snippet.pieces); + const examHitCount = allSnippets.filter((snippet) => snippet.snippetType === "past_exam_question").length; + + return { + id: String(mainTopic.id || "").trim(), + topic: String(mainTopic.title || "Topic").trim(), + canonical_topic: String(mainTopic.id || "").trim(), + parent_topic: String(parentTopic.title || "Topic Group").trim(), + parent_topic_id: String(parentTopic.id || "").trim(), + summary: String(mainTopic.summary || "").trim(), + search_text: String(mainTopic.search_text || `${mainTopic.title || ""} ${parentTopic.title || ""}`).trim(), + weeks, + related_weeks: relatedWeeks, + topic_meta: { + week: mainWeek, + topic_order: Number(mainTopic.topic_order || 0), + }, + exam_stats: { + total_hits: examHitCount, + coverage_count: allPieces.length, + }, + sections, + snippetCount: allSnippets.length, + pieceCount: allPieces.length, + }; +} + +function normalizeExamSection(section) { + if (!section || typeof section !== "object") { + return null; + } + + const snippets = Array.isArray(section.snippets) + ? section.snippets + .map(normalizeExamSnippet) + .filter(Boolean) + .sort((a, b) => Number(a.order || 0) - Number(b.order || 0)) + : []; + + return { + key: String(section.key || "").trim(), + title: String(section.title || EXAM_BUILDER_SECTION_LABELS[section.key] || humanizeTopic(section.key || "Section")).trim(), + description: String(section.description || EXAM_BUILDER_SECTION_DESCRIPTIONS[String(section.key || "").trim()] || "").trim(), + initialVisibleCount: Math.max(1, Number(section.initial_visible_count || 0) || 4), + snippets, + }; +} + +function normalizeExamSnippet(snippet) { + if (!snippet || typeof snippet !== "object") { + return null; + } + + const pieces = Array.isArray(snippet.pieces) + ? snippet.pieces + .map(normalizeExamPiece) + .filter(Boolean) + .sort((a, b) => Number(a.order || 0) - Number(b.order || 0)) + : []; + + return { + id: String(snippet.id || "").trim(), + title: String(snippet.title || "Snippet").trim(), + order: Number(snippet.order || 0), + snippetType: String(snippet.snippet_type || "general_snippet").trim(), + parentTopic: String(snippet.parent_topic || "").trim(), + mainTopic: String(snippet.main_topic || "").trim(), + mainWeek: Number(snippet.main_week || 0), + relatedTopics: Array.isArray(snippet.related_topics) + ? snippet.related_topics.map((value) => String(value || "").trim()).filter(Boolean) + : [], + relatedWeeks: Array.isArray(snippet.related_weeks) + ? snippet.related_weeks.map((value) => Number(value)).filter((value) => Number.isFinite(value) && value > 0) + : [], + summary: String(snippet.summary || "").trim(), + sourceRefs: Array.isArray(snippet.source_refs) ? deepClone(snippet.source_refs) : [], + pieces, + }; +} + +function normalizeExamPiece(piece) { + if (!piece || typeof piece !== "object" || !piece.id) { + return null; + } + + return { + id: String(piece.id || "").trim(), + sourcePieceId: String(piece.source_piece_id || "").trim(), + pieceType: String(piece.piece_type || "explanation").trim(), + title: String(piece.title || "Piece").trim(), + order: Number(piece.order || 0), + content: deepClone(piece.content || {}), + selectable: piece.selectable !== false, + sourceRefs: Array.isArray(piece.source_refs) ? deepClone(piece.source_refs) : [], + }; +} + +function getExamCardSections(card) { + return Array.isArray(card?.sections) ? card.sections : []; +} + +function getExamSection(card, sectionKey) { + return getExamCardSections(card).find((section) => section.key === sectionKey) || null; +} + +function getExamSnippet(card, snippetId) { + return getExamCardSections(card).flatMap((section) => section.snippets).find((snippet) => snippet.id === snippetId) || null; +} + +function findExamPieceContext(card, pieceId) { + for (const section of getExamCardSections(card)) { + for (const snippet of section.snippets) { + const piece = snippet.pieces.find((entry) => entry.id === pieceId); + if (piece) { + return { section, snippet, piece }; + } + } + } + return null; +} + +function getAllSelectablePieceIds(card) { + return getExamCardSections(card) + .flatMap((section) => section.snippets) + .flatMap((snippet) => snippet.pieces) + .filter((piece) => piece.selectable) + .map((piece) => piece.id); +} + +function getSectionSelectablePieceIds(card, sectionKey) { + const section = getExamSection(card, sectionKey); + if (!section) { + return []; + } + return section.snippets.flatMap((snippet) => snippet.pieces.filter((piece) => piece.selectable).map((piece) => piece.id)); +} + +function getSnippetSelectablePieceIds(card, snippetId) { + const snippet = getExamSnippet(card, snippetId); + if (!snippet) { + return []; + } + return snippet.pieces.filter((piece) => piece.selectable).map((piece) => piece.id); +} diff --git a/app/preview-card-render.js b/app/preview-card-render.js index 852466f..9d556d4 100644 --- a/app/preview-card-render.js +++ b/app/preview-card-render.js @@ -10,97 +10,25 @@ function buildPreviewCard(entry, layout) { const dragHint = locked ? "🔒" : "⋮"; const dragHintTitle = locked ? "Card locked" : "Drag card"; - const keyPointBlocks = []; - const aiQuestionBlocks = []; - const exampleBlocks = []; - const recommendedBlocks = []; - const additionalBlocks = []; - cards.forEach((sourceCard) => { const selection = selectionsByCard[sourceCard.id]; if (!selection) { return; } - ensureSelectionOverrides(selection); - if (selection.sections.aiQuestions) { - commonQuestionItems(sourceCard) - .filter((item) => (selection.selected.aiQuestions || []).includes(item.id)) - .forEach((item) => { - aiQuestionBlocks.push(renderPreviewCommonQuestion(previewId, sourceCard, selection, item)); - }); - } - - if (selection.sections.keyPoints) { - getSelectedKeyPointGroups(sourceCard, selection).forEach((group) => { - keyPointBlocks.push(renderPreviewKeyPointGroup(sourceCard, selection, group)); - }); - } + getExamCardSections(sourceCard).forEach((section) => { + const snippetBlocks = section.snippets + .map((snippet) => renderPreviewSnippetBlock(previewId, sourceCard, selection, section, snippet)) + .filter(Boolean); - if (selection.sections.aiExamples) { - usefulAIExamples(sourceCard) - .filter((item) => selection.selected.aiExamples.includes(item.id)) - .forEach((item) => { - const effective = getPreviewAIExampleOverride(selection, item.id, item); - const kindLabel = item.kind === "incorrect" ? "Incorrect" : "Correct"; - exampleBlocks.push(` -
    - ${renderPreviewItemActions(previewId, sourceCard.id, "aiExample", item.id, "aiExamples")} -

    ${escapeHtml(kindLabel)} • ${renderInlineCode(effective.title || "Code example")}

    - ${renderCodeBlock(effective.code || "")} - ${effective.output ? `

    Output / Result:

    ${renderOutputBlock(effective.output || "")}` : ""} -
    - `); + if (snippetBlocks.length) { + sections.push({ + label: section.title, + content: snippetBlocks.join(""), }); - } - - if (selection.sections.recommended) { - getSelectedSourceItemsForPreview(sourceCard, selection, "recommended").forEach((sourceItem) => { - recommendedBlocks.push(renderPreviewSourceItem(previewId, sourceCard, selection, sourceItem, "recommended")); - }); - } - - if (selection.sections.additional) { - getSelectedSourceItemsForPreview(sourceCard, selection, "additional").forEach((sourceItem) => { - additionalBlocks.push(renderPreviewSourceItem(previewId, sourceCard, selection, sourceItem, "additional")); - }); - } - }); - - if (keyPointBlocks.length) { - sections.push({ - label: "Key Points for Reference", - content: `
    ${keyPointBlocks.join("")}
    `, - }); - } - - if (aiQuestionBlocks.length) { - sections.push({ - label: "Common Exam Questions", - content: aiQuestionBlocks.join(""), - }); - } - - if (exampleBlocks.length) { - sections.push({ - label: "Code Examples", - content: exampleBlocks.join(""), - }); - } - - if (recommendedBlocks.length) { - sections.push({ - label: "Recommended", - content: recommendedBlocks.join(""), - }); - } - - if (additionalBlocks.length) { - sections.push({ - label: "Additional", - content: additionalBlocks.join(""), + } }); - } + }); if (!sections.length) { return null; @@ -161,7 +89,7 @@ function buildPreviewCard(entry, layout) { return cardElement; } -function renderPreviewItemActions(previewCardId, sourceCardId, itemType, itemId, sectionKey) { +function renderPreviewItemActions(previewCardId, sourceCardId, pieceId, itemType) { return `
    - ${bundles - .map((bundle) => renderWeekSidebarSection(bundle, activeTopicId)) - .join("")} + ${parentTopics.map((parentTopic) => renderParentSidebarSection(parentTopic, activeTopicId)).join("")}
    `; } -function renderWeekSidebarSection(bundle, activeTopicId) { - const expanded = Boolean(state.navigation.expandedWeeks[String(bundle.week)]); - const summary = getWeekSelectionSummary(bundle); - const topicCountLabel = `${bundle.cards.length} topic${bundle.cards.length === 1 ? "" : "s"}`; + +function renderParentSidebarSection(parentTopic, activeTopicId) { + const expanded = Boolean(state.navigation.expandedParents[parentTopic.id]); + const summary = getParentSelectionSummary(parentTopic); + const topicCountLabel = `${parentTopic.cards.length} topic${parentTopic.cards.length === 1 ? "" : "s"}`; return ` -
    +
    - ${bundle.groups.map((group) => renderSidebarCourseGroup(group, bundle.week, activeTopicId)).join("")} -
    -
    - `; -} -function renderSidebarCourseGroup(group, week, activeTopicId) { - const groupSelection = getWeekSelectionSummary(group); - const countLabel = `${group.cards.length} card${group.cards.length === 1 ? "" : "s"}`; - const metaBits = [countLabel]; - if (groupSelection.topics > 0) { - metaBits.push(`${groupSelection.topics} selected`); - } - if (group.isDefault) { - return ` -
    -
    - ${group.cards.map((card) => renderSidebarTopicButton(card, week, activeTopicId)).join("")} -
    -
    - `; - } - return ` -
    -
    -
    - ${escapeHtml(group.title)} - ${escapeHtml(metaBits.join(" • "))} + ${parentTopic.summary ? `

    ${escapeHtml(parentTopic.summary)}

    ` : ""} +
    +
    + ${parentTopic.cards.map((card) => renderSidebarTopicButton(card, parentTopic.id, activeTopicId)).join("")} +
    -
    - ${group.cards.map((card) => renderSidebarTopicButton(card, week, activeTopicId)).join("")} -
    -
    +
    `; } -function renderSidebarTopicButton(card, week, activeTopicId) { + +function renderSidebarTopicButton(card, parentId, activeTopicId) { const counts = getSelectionCounts(card); const isActive = activeTopicId === card.id; const badges = []; - if (card.exam_stats.total_hits > 0) { - badges.push(`${card.exam_stats.total_hits} exam`); - } if (counts.total > 0) { badges.push(`${counts.total} selected`); } @@ -131,52 +109,43 @@ function renderSidebarTopicButton(card, week, activeTopicId) { type="button" data-role="open-topic" data-card-id="${escapeHtml(card.id)}" - data-week="${week}" + data-parent-id="${escapeHtml(parentId)}" > ${escapeHtml(humanizeTopic(card.topic))} - ${escapeHtml(badges.join(" • ") || "Open topic")} + ${badges.length ? `${escapeHtml(badges.join(" • "))}` : ""} `; } -function renderTopicDetail(card, bundle, group) { + +function renderTopicDetail(card, parentTopic) { const draft = ensureDraft(card); - const split = getSourceSplit(card); - const keyPoints = keyPointGroups(card); - const aiExamples = usefulAIExamples(card); - const subtopics = getCardSubtopics(card); const selectedCounts = getSelectionCounts(card, draft); - const weekLabel = Array.isArray(card.weeks) && card.weeks.length ? card.weeks.map((week) => `W${week}`).join(" · ") : `W${bundle.week}`; - const commonQuestions = getCommonQuestionItems(card); - const examHitsLabel = card.exam_stats.total_hits > 0 ? `${card.exam_stats.total_hits} exam hits` : "Course material only"; - const groupTitle = group?.isDefault ? "Lecture-aligned topic" : group?.title || "Lecture-aligned topic"; - const contextPanels = [ - renderSubtopicOverview(subtopics), - ] - .filter(Boolean) - .join(""); + const weekLabel = Array.isArray(card.weeks) && card.weeks.length ? card.weeks.map((week) => `W${week}`).join(" · ") : "No week tag"; + const visibleSections = getExamCardSections(card).filter((section) => section.snippets.length > 0); + return ` -
    +
    - ${escapeHtml(`Week ${bundle.week}`)} - ${escapeHtml(groupTitle)} + ${escapeHtml(parentTopic.title)} + ${escapeHtml(weekLabel)}
    -

    ${escapeHtml(`Source weeks ${weekLabel} · ${examHitsLabel}`)}

    +

    ${escapeHtml(`${card.snippetCount} curated snippets · ${card.pieceCount} selectable pieces`)}

    ${escapeHtml(humanizeTopic(card.topic))}

    - ${card.sections.ai_summary?.content ? `

    ${renderInlineCode(normalizeTruncatedDisplayText(card.sections.ai_summary.content))}

    ` : ""} + ${card.summary ? `

    ${renderInlineCode(card.summary)}

    ` : ""}
    - ${contextPanels ? `
    ${contextPanels}
    ` : ""} - ${renderCommonQuestionRail(card, draft, commonQuestions)} - ${renderKeyPointRail(card, draft, keyPoints)} - ${renderExampleRail(card, draft, aiExamples)} - ${renderSourceRail(card, draft, "recommended", "Recommended Snippets", split.recommended)} - ${renderSourceRail(card, draft, "additional", "Additional Snippets", split.additional)} + ${visibleSections.map((section) => renderSectionBlock(card, draft, section)).join("")}
    @@ -202,264 +166,157 @@ function renderTopicDetail(card, bundle, group) {
    `; } -function renderSectionHeaderBar(card, draft, sectionKey, title, countText, description = "") { - const enabled = Boolean(draft.sections[sectionKey]); + +function renderSectionBlock(card, draft, section) { + const selectedCount = getSectionSelectedCount(card, draft, section.key); + const isExpanded = Boolean(draft.ui.expandedSections?.[section.key]); + const visibleSnippets = isExpanded ? section.snippets : section.snippets.slice(0, section.initialVisibleCount); + const hiddenCount = Math.max(0, section.snippets.length - visibleSnippets.length); + return ` -
    -
    -

    ${escapeHtml(title)}

    - ${description ? `

    ${escapeHtml(description)}

    ` : ""} -
    -
    - ${escapeHtml(countText)} -
    - `; -} -function renderKeyPointRail(card, draft, groups) { - const selectedSet = new Set(draft.selected.keyPoints || []); - const selectableIds = new Set(keyPointSelectableIds(card)); - const selectedCount = [...selectedSet].filter((id) => selectableIds.has(id)).length; - const grouped = groupItemsBySubtopic(card, groups, (item) => item.subtopic_id, (item) => item.subtopic_title); - const body = groups.length - ? grouped - .map((subtopicGroup) => { - const itemsHtml = subtopicGroup.items - .map((group) => { - const pointChecked = selectedSet.has(group.id); - const detailsHtml = group.details.length - ? group.details - .map((detail) => { - const checked = selectedSet.has(detail.id); - return ` -
    - - ${renderDetailPreview(detail)} -
    - `; - }) - .join("") - : ""; - return ` -
    - -
    - ${detailsHtml ? `
    ${detailsHtml}
    ` : ""} -
    -
    - `; - }) - .join(""); - return renderSubtopicRailGroup(subtopicGroup, itemsHtml); - }) - .join("") - : renderEmptyRailCopy("No key points are available for this topic."); - return ` -
    - ${renderSectionHeaderBar( - card, - draft, - "keyPoints", - "Key Points", - `${selectedCount}/${selectableIds.size} selected`, - "Keep the facts and optional detail blocks that truly earn space on the sheet." - )} -
    ${body}
    `; } -function renderExampleRail(card, draft, items) { - const selectedCount = items.filter((item) => draft.selected.aiExamples.includes(item.id)).length; - const grouped = groupItemsBySubtopic(card, items, (item) => item.subtopic_id, (item) => item.subtopic_title); - const body = items.length - ? grouped - .map((subtopicGroup) => { - const itemsHtml = subtopicGroup.items - .map((item) => { - const checked = draft.selected.aiExamples.includes(item.id); - const kindLabel = item.kind === "incorrect" ? "Incorrect" : "Correct"; - return ` -
    - -
    - ${renderCodeBlock(item.code || "")} - ${item.output ? `

    Output / Result:

    ${renderOutputBlock(item.output || "")}` : ""} - ${item.why ? `

    ${renderInlineCode(item.why)}

    ` : ""} -
    -
    - `; - }) - .join(""); - return renderSubtopicRailGroup(subtopicGroup, itemsHtml); - }) - .join("") - : renderEmptyRailCopy("No code examples are available for this topic."); + +function renderSnippetCard(card, draft, section, snippet) { + const selectedCount = getSnippetSelectedCount(card, draft, snippet.id); return ` -
    - ${renderSectionHeaderBar( - card, - draft, - "aiExamples", - "Code Examples", - `${selectedCount}/${items.length} selected`, - "Choose the patterns you want to be able to reproduce from memory." - )} -
    ${body}
    -
    +
    +
    +
    +
    + ${isPastExamSnippet(snippet) ? `Past exam` : ""} +
    +
    ${escapeHtml(snippet.title)}
    + ${snippet.summary ? `

    ${renderInlineCode(snippet.summary)}

    ` : ""} +

    ${escapeHtml(`${selectedCount}/${getSnippetSelectablePieceIds(card, snippet.id).length} pieces selected`)}

    +
    +
    + + +
    +
    +
    + ${snippet.pieces.map((piece) => renderPieceSelector(card, draft, section, snippet, piece)).join("")} +
    +
    `; } -function renderCommonQuestionRail(card, draft, items) { - const selectedCount = items.filter((item) => (draft.selected.aiQuestions || []).includes(item.id)).length; - const body = items.length - ? `
    ${items - .map((item) => { - const checked = (draft.selected.aiQuestions || []).includes(item.id); - return ` -
    - -
    - ${item.detail ? `

    ${renderInlineCode(item.detail)}

    ` : ""} - ${item.extra ? `

    ${renderInlineCode(item.extra)}

    ` : ""} - ${item.table ? renderMiniTable(item.table) : ""} - ${item.code ? renderCodeBlock(item.code) : ""} -
    -
    - `; - }) - .join("")}
    ` - : renderEmptyRailCopy("No common exam questions are available for this topic."); - +function renderPieceSelector(card, draft, section, snippet, piece) { + const selectedSet = new Set(draft.selected.pieces || []); + const checked = selectedSet.has(piece.id); + const effectivePiece = getPieceOverride(draft, piece); return ` -
    - ${renderSectionHeaderBar( - card, - draft, - "aiQuestions", - "Common Exam Questions", - `${selectedCount}/${items.length} selected`, - "Keep the answer patterns and traps you want printed directly on the cheat sheet." - )} - ${body} -
    +
    + +
    + ${renderPieceBody(effectivePiece)} +
    +
    `; } -function renderSourceRail(card, draft, sectionKey, title, items) { - const selectedIds = draft.selected[sectionKey] || []; - const selectedCount = items.filter((item) => selectedIds.includes(item.id)).length; - const grouped = groupItemsBySubtopic(card, items, (item) => item.subtopicId, (item) => item.subtopicTitle); - const body = items.length - ? grouped - .map((subtopicGroup) => { - const itemsHtml = subtopicGroup.items - .map((sourceItem) => { - const checked = selectedIds.includes(sourceItem.id); - return ` -
    - -
    - ${renderSourceItemBody(sourceItem)} -
    -
    - `; - }) - .join(""); - return renderSubtopicRailGroup(subtopicGroup, itemsHtml); - }) - .join("") - : renderEmptyRailCopy("No snippets are available in this section."); - return ` -
    - ${renderSectionHeaderBar( - card, - draft, - sectionKey, - title, - `${selectedCount}/${items.length} selected`, - sectionKey === "recommended" - ? "High-value lecture and exam snippets that usually deserve first priority." - : "Extra supporting snippets for edge cases, comparisons, and reminders." - )} -
    ${body}
    -
    - `; +function renderPieceBody(piece) { + const content = piece.content || {}; + if (piece.pieceType === "reference_table") { + const text = String(content.text || "").trim(); + const table = { + headers: Array.isArray(content.headers) ? content.headers : [], + rows: Array.isArray(content.rows) ? content.rows : [], + }; + return ` + ${text ? `

    ${renderInlineCode(text)}

    ` : ""} + ${table.headers.length && table.rows.length ? renderMiniTable(table) : ""} + `; + } + + if (piece.pieceType === "code_example") { + return ` + ${content.text ? `

    ${renderInlineCode(content.text)}

    ` : ""} + ${content.code ? renderCodeBlock(content.code) : ""} + ${content.output ? `

    Output:

    ${renderOutputBlock(content.output)}` : ""} + `; + } + + if (piece.pieceType === "past_exam_piece") { + return ` + ${renderQuestionContent(content.question || "", content.code_context || "")} + ${renderOptions(content.options || {})} + ${content.correct ? `

    Correct: ${escapeHtml(String(content.correct).toUpperCase())}

    ` : ""} + ${content.explanation ? `

    ${renderInlineCode(content.explanation)}

    ` : ""} + `; + } + + const text = String(content.text || "").trim(); + return text ? `

    ${renderInlineCode(text)}

    ` : ""; } diff --git a/app/splash-storage.js b/app/splash-storage.js index 9494e23..d1ef500 100644 --- a/app/splash-storage.js +++ b/app/splash-storage.js @@ -1,5 +1,5 @@ function setLoadingState() { - refs.cardHost.innerHTML = `

    Loading week bundles...

    `; + refs.cardHost.innerHTML = `

    Loading exam topic explorer...

    `; } function maybeShowSplash() { @@ -77,15 +77,13 @@ function resetAppProgress() { lastPersistedPayload = ""; state.filters.search = ""; - state.filters.onlyExam = false; - state.filters.minHits = 0; state.filters.weeks = new Set(CANONICAL_WEEK_ORDER); - state.drafts = {}; state.navigation = buildDefaultNavigationState(); state.previewHistory = []; state.openDrawer = ""; state.previewCards = {}; + state.previewEntries = {}; state.previewZCounter = 1; state.layout = { fontFamily: "'Manrope', sans-serif", @@ -102,8 +100,10 @@ function resetAppProgress() { gridRows: 6, }; + renderWeekFilterControls(); syncFilterControls(); applyLayoutVariables(); + ensureExplorerNavigation(getFilteredParentBundles()); closeTopicSidebar(); setView("swipe"); renderAll(); @@ -117,6 +117,8 @@ function hydratePersistedState() { } const cardIds = new Set(state.cards.map((card) => card.id)); + const parentIds = new Set(state.parentTopics.map((parentTopic) => parentTopic.id)); + const validWeeks = new Set(CANONICAL_WEEK_ORDER); if (raw.layout && typeof raw.layout === "object") { const fontAliases = new Map([ @@ -169,18 +171,12 @@ function hydratePersistedState() { if (raw.filters && typeof raw.filters === "object") { state.filters.search = typeof raw.filters.search === "string" ? raw.filters.search : state.filters.search; - if (typeof raw.filters.onlyExam === "boolean") { - state.filters.onlyExam = raw.filters.onlyExam; - } - if (Number.isFinite(raw.filters.minHits)) { - state.filters.minHits = clamp(Number(raw.filters.minHits), 0, 3); - } if (Array.isArray(raw.filters.weeks)) { - const validWeeks = raw.filters.weeks + const weeks = raw.filters.weeks .map((value) => Number(value)) - .filter((value) => CANONICAL_WEEK_ORDER.includes(value)); - if (validWeeks.length) { - state.filters.weeks = new Set(validWeeks); + .filter((value) => validWeeks.has(value)); + if (weeks.length) { + state.filters.weeks = new Set(weeks); } } } @@ -191,27 +187,43 @@ function hydratePersistedState() { if (!cardIds.has(cardId) || !draft || typeof draft !== "object") { return; } - hydratedDrafts[cardId] = deepClone(draft); + + const card = state.cards.find((entry) => entry.id === cardId); + const validPieceIds = new Set(getAllSelectablePieceIds(card)); + const selectedPieces = Array.isArray(draft.selected?.pieces) + ? draft.selected.pieces.filter((pieceId) => validPieceIds.has(pieceId)) + : []; + hydratedDrafts[cardId] = { + ui: { + expandedSections: deepClone(draft.ui?.expandedSections || {}), + }, + selected: { + pieces: [...new Set(selectedPieces)], + }, + overrides: { + pieces: deepClone(draft.overrides?.pieces || {}), + }, + }; }); state.drafts = hydratedDrafts; } if (raw.navigation && typeof raw.navigation === "object") { const nextNavigation = buildDefaultNavigationState(); - const activeWeek = Number(raw.navigation.activeWeek); - if (CANONICAL_WEEK_ORDER.includes(activeWeek)) { - nextNavigation.activeWeek = activeWeek; + const activeParentId = String(raw.navigation.activeParentId || "").trim(); + if (parentIds.has(activeParentId)) { + nextNavigation.activeParentId = activeParentId; } const activeTopicId = String(raw.navigation.activeTopicId || "").trim(); if (cardIds.has(activeTopicId)) { nextNavigation.activeTopicId = activeTopicId; } - if (raw.navigation.expandedWeeks && typeof raw.navigation.expandedWeeks === "object") { - CANONICAL_WEEK_ORDER.forEach((week) => { - const key = String(week); - if (typeof raw.navigation.expandedWeeks[key] === "boolean") { - nextNavigation.expandedWeeks[key] = raw.navigation.expandedWeeks[key]; - } + if (raw.navigation.expandedParents && typeof raw.navigation.expandedParents === "object") { + state.parentTopics.forEach((parentTopic, index) => { + const fallbackValue = index === 0; + const persistedValue = raw.navigation.expandedParents[parentTopic.id]; + nextNavigation.expandedParents[parentTopic.id] = + typeof persistedValue === "boolean" ? persistedValue : fallbackValue; }); } if (typeof raw.navigation.mobileSidebarOpen === "boolean") { @@ -259,14 +271,10 @@ function getPersistedRawState() { function syncFilterControls() { refs.searchInput.value = state.filters.search; - refs.onlyExamToggle.checked = state.filters.onlyExam; - refs.minHitsSelect.value = String(state.filters.minHits); - if (refs.weekFilterList) { - refs.weekFilterList.querySelectorAll(".weekCheck").forEach((checkbox) => { - const week = Number(checkbox.value); - checkbox.checked = state.filters.weeks.has(week); - }); - } + refs.weekFilterList?.querySelectorAll(".weekCheck").forEach((checkbox) => { + const week = Number(checkbox.value); + checkbox.checked = state.filters.weeks.has(week); + }); } function schedulePersistState() { @@ -286,8 +294,6 @@ function persistAppState() { const payload = { filters: { search: state.filters.search, - onlyExam: state.filters.onlyExam, - minHits: state.filters.minHits, weeks: [...state.filters.weeks], }, drafts: state.drafts, diff --git a/app/state-and-init.js b/app/state-and-init.js index 9c3678c..431fa74 100644 --- a/app/state-and-init.js +++ b/app/state-and-init.js @@ -1,16 +1,6 @@ -const EXAM_LABELS = { - trial_midterm: "Trial 24/25", - midterm_2023: "Trial 22/23", - midterm_2024: "Trial 23/24", - extra_practice: "Extra Practice", - intro_python_sample_final_24_25: "Sample Final 24/25", -}; - -const AI_GENERATION_NOTE = "AI-generated from practice exam questions, lecture snippets, notebook snippets, and trap-pattern context."; -const KEY_POINTS_GENERATION_NOTE = "AI-generated key points and optional details, then filtered against available course materials."; const SPLASH_STORAGE_KEY = "python_midterm_splash_seen_v3"; -const APP_STATE_STORAGE_KEY = "python_midterm_app_state_v7"; -const TOPIC_CARDS_DATASET_VERSION = "2026-03-22-curation-pass-5"; +const APP_STATE_STORAGE_KEY = "python_midterm_app_state_v9"; +const EXAM_BUILDER_DATASET_VERSION = "2026-03-24-manual-curation-hard-cut"; const CANONICAL_WEEK_ORDER = [1, 2, 3, 4, 5, 6]; const DEFAULT_PAGE_INNER_WIDTH = 758; const DEFAULT_PAGE_INNER_HEIGHT = 1079; @@ -18,19 +8,17 @@ const DEFAULT_PAGE_INNER_HEIGHT = 1079; function buildDefaultNavigationState() { return { activeTopicId: "", - activeWeek: CANONICAL_WEEK_ORDER[0], - expandedWeeks: Object.fromEntries(CANONICAL_WEEK_ORDER.map((week, index) => [String(week), index === 0])), + activeParentId: "", + expandedParents: {}, mobileSidebarOpen: false, }; } const state = { + parentTopics: [], cards: [], - deckGroups: [], filters: { search: "", - onlyExam: false, - minHits: 0, weeks: new Set(CANONICAL_WEEK_ORDER), }, drafts: {}, @@ -39,6 +27,7 @@ const state = { view: "swipe", openDrawer: "", previewCards: {}, + previewEntries: {}, previewZCounter: 1, layout: { fontFamily: "'Manrope', sans-serif", @@ -95,9 +84,6 @@ const refs = { sheetStage: document.getElementById("sheetStage"), searchInput: document.getElementById("searchInput"), - onlyExamToggle: document.getElementById("onlyExamToggle"), - minHitsSelect: document.getElementById("minHitsSelect"), - skipToPreviewBtn: document.getElementById("skipToPreviewBtn"), goToSwipeBtn: document.getElementById("goToSwipeBtn"), goToPreviewBtn: document.getElementById("goToPreviewBtn"), @@ -158,25 +144,27 @@ const previewPointerState = { grabOffsetY: 0, }; - async function init() { bindEvents(); syncViewButtons(); - renderWeekFilterControls(); applyLayoutVariables(); setLoadingState(); maybeShowSplash(); try { - const response = await fetch(`./topic_cards.json?v=${encodeURIComponent(TOPIC_CARDS_DATASET_VERSION)}`); + const response = await fetch(`./data/exam_builder_topics.json?v=${encodeURIComponent(EXAM_BUILDER_DATASET_VERSION)}`); if (!response.ok) { - throw new Error(`Failed to load topic_cards.json (${response.status})`); + throw new Error(`Failed to load exam_builder_topics.json (${response.status})`); } - const data = await response.json(); - state.cards = Array.isArray(data.cards) ? data.cards : []; - state.deckGroups = Array.isArray(data.deck_groups) ? data.deck_groups : []; + + const payload = await response.json(); + const normalized = normalizeExamBuilderPayload(payload); + state.parentTopics = normalized.parentTopics; + state.cards = normalized.cards; + + renderWeekFilterControls(); hydratePersistedState(); - ensureExplorerNavigation(getFilteredWeekBundles()); + ensureExplorerNavigation(getFilteredParentBundles()); syncFilterControls(); applyLayoutVariables(); renderAll(); @@ -185,9 +173,9 @@ async function init() { } } catch (error) { refs.cardHost.innerHTML = `
    -

    Could not load topic_cards.json.

    +

    Could not load data/exam_builder_topics.json.

    ${escapeHtml(error.message)}

    -

    Serve this folder with python3 -m http.server 4173 and open http://127.0.0.1:4173.

    +

    Refresh the manually curated dataset at data/exam_builder_topics.json, then serve the repo with python3 -m http.server 4173.

    `; } } @@ -211,16 +199,6 @@ function bindEvents() { renderAll(); }); - refs.onlyExamToggle.addEventListener("change", (event) => { - state.filters.onlyExam = Boolean(event.target.checked); - renderAll(); - }); - - refs.minHitsSelect.addEventListener("change", (event) => { - state.filters.minHits = Number(event.target.value); - renderAll(); - }); - refs.skipToPreviewBtn.addEventListener("click", () => setView("preview")); refs.goToSwipeBtn.addEventListener("click", () => setView("swipe")); refs.goToPreviewBtn.addEventListener("click", () => setView("preview")); @@ -266,11 +244,6 @@ function bindEvents() { } closeOpenInfoPopovers(); }); - const repositionOpenPopovers = () => { - document.querySelectorAll(".info-chip.open").forEach((chip) => positionInfoPopover(chip)); - }; - window.addEventListener("resize", repositionOpenPopovers); - window.addEventListener("scroll", repositionOpenPopovers, true); document.addEventListener("keydown", (event) => { if (isSplashVisible()) { @@ -379,7 +352,6 @@ function bindEvents() { refs.printBtn.addEventListener("click", printGeneratedPdf); refs.previewUndoBtn?.addEventListener("click", () => undoLastPreviewChange()); - refs.exportPngBtn.addEventListener("click", exportPng); refs.exportPdfBtn.addEventListener("click", exportPdf); diff --git a/app/topic-selection.js b/app/topic-selection.js index f437103..b5c6c3a 100644 --- a/app/topic-selection.js +++ b/app/topic-selection.js @@ -1,395 +1,159 @@ -function usefulLectureSnippets(card) { - const snippets = card.sections.lecture_snippets || []; - return snippets - .map((snippet) => { - const filteredCode = (snippet.code_examples || []).filter((example) => !isLowValueSnippet(example.code || "")); - return { - ...snippet, - code_examples: filteredCode, - }; - }) - .filter((snippet) => Boolean(snippet.explanation || snippet.question || (snippet.code_examples || []).length)); -} - -function usefulNotebookSnippets(card) { - return (card.sections.notebook_snippets || []).filter((snippet) => { - const source = snippet.source || ""; - const hasPrintCall = /\bprint\s*\(/.test(source); - const hasOutputs = (snippet.outputs || []).length > 0; - return !isLowValueSnippet(source) && (!hasPrintCall || hasOutputs); - }); -} - -function usefulAIExamples(card) { - return (card.sections.ai_examples || []) - .filter((item) => (item.code || "").trim().length > 0) - .map((item) => ({ - ...item, - subtopic_id: item.subtopic_id || "", - subtopic_title: item.subtopic_title || "", - })); -} - -function commonQuestionItems(card) { - return getCommonQuestionItems(card); -} - -function commonQuestionSelectableIds(card) { - return commonQuestionItems(card).map((item) => item.id); -} - -function normalizeKeyPointDetails(baseId, details) { - return (details || []) - .map((detail, idx) => { - const id = String(detail?.id || `${baseId}-d${idx + 1}`).trim(); - const kindRaw = String(detail?.kind || "example").trim().toLowerCase(); - const kind = ["example", "table", "commands", "explanation"].includes(kindRaw) ? kindRaw : "example"; - const title = String(detail?.title || "Optional detail").trim(); - const text = String(detail?.text || "").trim(); - const code = normalizeNewlines(detail?.code || "").trim(); - const table = normalizeMiniTable(detail?.table); - - if (!id || (!text && !code && !table)) { - return null; - } - - return { - id, - kind, - title, - text, - code, - table, - }; - }) - .filter(Boolean); -} - -function normalizeMiniTable(rawTable) { - if (!rawTable || typeof rawTable !== "object") { - return null; - } - - const headers = Array.isArray(rawTable.headers) - ? rawTable.headers.map((value) => String(value || "").trim()).filter((value) => value.length > 0) - : []; - const rows = Array.isArray(rawTable.rows) - ? rawTable.rows - .map((row) => (Array.isArray(row) ? row.map((value) => String(value || "").trim()) : [])) - .filter((row) => row.length > 0 && row.some((cell) => cell.length > 0)) - : []; - - if (!headers.length || !rows.length) { - return null; - } - - return { headers, rows }; -} - -function keyPointGroups(card) { - return (card.sections.key_points_to_remember || []) - .filter((item) => item && (item.text || "").trim().length > 0) - .map((item, idx) => { - const id = String(item.id || `kp-${idx + 1}`).trim(); - const text = String(item.text || "").trim(); - return { - id, - text, - subtopic_id: String(item.subtopic_id || "").trim(), - subtopic_title: String(item.subtopic_title || "").trim(), - details: normalizeKeyPointDetails(id, item.details || []), - }; - }); -} - -function keyPointSelectableIds(card) { - const ids = []; - keyPointGroups(card).forEach((group) => { - ids.push(group.id); - group.details.forEach((detail) => ids.push(detail.id)); - }); - return ids; -} - -function buildSourceItems(card) { - const items = []; - - (card.sections.exam_questions || []).forEach((item) => { - items.push({ - id: item.id, - sourceType: "exam", - priority: 0, - header: `Exam • Q${item.number || "?"} • ${formatExamLabel(item.exam_label)}`, - subtopicId: item.subtopic_id || "", - subtopicTitle: item.subtopic_title || "", - item, - }); - }); - - usefulLectureSnippets(card).forEach((item) => { - items.push({ - id: item.id, - sourceType: "lecture", - priority: 1, - header: `Lecture • ${item.topic || "snippet"} • W${item.week || "?"}`, - subtopicId: item.subtopic_id || "", - subtopicTitle: item.subtopic_title || "", - item, - }); - }); - - usefulNotebookSnippets(card).forEach((item) => { - items.push({ - id: item.id, - sourceType: "notebook", - priority: 2, - header: `Notebook • W${item.week || "?"} cell ${item.cell_index || "?"} • ${item.topic || ""}`, - subtopicId: item.subtopic_id || "", - subtopicTitle: item.subtopic_title || "", - item, - }); - }); - - items.sort((a, b) => a.priority - b.priority); - return items; -} - -function getSourceSplit(card) { - const allItems = buildSourceItems(card); - const byId = new Map(allItems.map((item) => [item.id, item])); - const recommendedIdsRaw = card.sections.recommended_ids || []; - const recommendedIds = recommendedIdsRaw.filter((id) => byId.has(id)); - const recommended = []; - - recommendedIds.forEach((id) => { - if (!recommended.some((item) => item.id === id)) { - recommended.push(byId.get(id)); - } - }); - - if (!recommended.length && allItems.length) { - const fallback = allItems.filter((item) => item.sourceType === "exam").slice(0, 4); - const extra = allItems - .filter((item) => item.sourceType !== "exam") - .slice(0, Math.max(0, 6 - fallback.length)); - recommended.push(...fallback, ...extra); - } - - const recSet = new Set(recommended.map((item) => item.id)); - const additional = allItems.filter((item) => !recSet.has(item.id)); - return { recommended, additional }; -} - -function getCardSubtopics(card) { - const subtopics = Array.isArray(card?.subtopics) ? card.subtopics : []; - return [...subtopics].sort((a, b) => Number(a?.order || 0) - Number(b?.order || 0)); -} - -function getSubtopicLookup(card) { - const lookup = new Map(); - getCardSubtopics(card).forEach((subtopic) => { - lookup.set(String(subtopic.id || ""), subtopic); - }); - return lookup; -} - -function groupItemsBySubtopic(card, items, getSubtopicId, getSubtopicTitle) { - const lookup = getSubtopicLookup(card); - const grouped = new Map(); - - getCardSubtopics(card).forEach((subtopic) => { - grouped.set(String(subtopic.id || ""), { - id: String(subtopic.id || ""), - title: String(subtopic.title || "Subtopic"), - summary: String(subtopic.summary || "").trim(), - items: [], - }); - }); - - items.forEach((item) => { - const explicitId = String(getSubtopicId(item) || "").trim(); - const explicitTitle = String(getSubtopicTitle(item) || "").trim(); - const fallbackSubtopic = getCardSubtopics(card)[0] || null; - const resolvedId = explicitId || String(fallbackSubtopic?.id || "misc"); - - if (!grouped.has(resolvedId)) { - grouped.set(resolvedId, { - id: resolvedId, - title: explicitTitle || lookup.get(resolvedId)?.title || "Subtopic", - summary: String(lookup.get(resolvedId)?.summary || "").trim(), - items: [], - }); - } - - grouped.get(resolvedId).items.push(item); - }); - - return [...grouped.values()].filter((group) => group.items.length > 0); -} - function ensureDraft(card) { if (state.drafts[card.id]) { return state.drafts[card.id]; } - const commonQuestionSection = card.sections.ai_common_questions || {}; - const commonQuestionCount = (commonQuestionSection.items || []).length || (commonQuestionSection.bullets || []).length; - const split = getSourceSplit(card); - const recommendedIds = split.recommended.map((item) => item.id); - const additionalIds = split.additional.map((item) => item.id); - const aiExampleIds = usefulAIExamples(card).map((item) => item.id); - const aiQuestionIds = commonQuestionSelectableIds(card); - const keyPointIds = keyPointSelectableIds(card); - state.drafts[card.id] = { ui: { - settingsOpen: false, - }, - sections: { - aiSummary: Boolean(card.sections.ai_summary?.content), - aiQuestions: commonQuestionCount > 0, - keyPoints: keyPointIds.length > 0, - aiExamples: aiExampleIds.length > 0, - recommended: recommendedIds.length > 0, - additional: additionalIds.length > 0, + expandedSections: {}, }, selected: { - aiQuestions: [], - aiExamples: [], - keyPoints: [], - recommended: [], - additional: [], + pieces: [], }, overrides: { - aiQuestions: {}, - keyPoints: {}, - keyPointDetails: {}, - aiExamples: {}, - sources: {}, + pieces: {}, }, }; - return state.drafts[card.id]; } function cloneDraft(draft) { return { ui: { - settingsOpen: Boolean(draft.ui?.settingsOpen), + expandedSections: deepClone(draft.ui?.expandedSections || {}), }, - sections: { ...draft.sections }, selected: { - aiQuestions: [...(draft.selected.aiQuestions || [])], - aiExamples: [...(draft.selected.aiExamples || [])], - keyPoints: [...(draft.selected.keyPoints || [])], - recommended: [...(draft.selected.recommended || [])], - additional: [...(draft.selected.additional || [])], + pieces: [...(draft.selected?.pieces || [])], + }, + overrides: { + pieces: deepClone(draft.overrides?.pieces || {}), }, - overrides: deepClone(draft.overrides || { aiQuestions: {}, keyPoints: {}, keyPointDetails: {}, aiExamples: {}, sources: {} }), }; } +function ensureSelectionOverrides(selection) { + if (!selection || typeof selection !== "object") { + return { pieces: {} }; + } + if (!selection.overrides || typeof selection.overrides !== "object") { + selection.overrides = {}; + } + if (!selection.overrides.pieces || typeof selection.overrides.pieces !== "object") { + selection.overrides.pieces = {}; + } + return selection.overrides; +} + function getRenderableSelection(card, draft) { if (!draft) { return null; } const normalized = cloneDraft(draft); - const aiExampleIds = new Set(usefulAIExamples(card).map((item) => item.id)); - const aiQuestionIds = new Set(commonQuestionSelectableIds(card)); - const keyPointIds = new Set(keyPointSelectableIds(card)); - const split = getSourceSplit(card); - const recommendedIds = new Set(split.recommended.map((item) => item.id)); - const additionalIds = new Set(split.additional.map((item) => item.id)); - - normalized.selected.aiQuestions = normalized.sections.aiQuestions - ? normalized.selected.aiQuestions.filter((id) => aiQuestionIds.has(id)) - : []; - normalized.selected.aiExamples = normalized.sections.aiExamples - ? normalized.selected.aiExamples.filter((id) => aiExampleIds.has(id)) - : []; - normalized.selected.keyPoints = normalized.sections.keyPoints - ? normalized.selected.keyPoints.filter((id) => keyPointIds.has(id)) - : []; - normalized.selected.recommended = normalized.sections.recommended - ? normalized.selected.recommended.filter((id) => recommendedIds.has(id)) - : []; - normalized.selected.additional = normalized.sections.additional - ? normalized.selected.additional.filter((id) => additionalIds.has(id)) - : []; - - const totalSelected = - normalized.selected.aiQuestions.length + - normalized.selected.aiExamples.length + - normalized.selected.keyPoints.length + - normalized.selected.recommended.length + - normalized.selected.additional.length; - - return totalSelected ? normalized : null; + const validIds = new Set(getAllSelectablePieceIds(card)); + normalized.selected.pieces = normalized.selected.pieces.filter((pieceId) => validIds.has(pieceId)); + const cleanOverrides = {}; + Object.entries(normalized.overrides.pieces || {}).forEach(([pieceId, value]) => { + if (validIds.has(pieceId) && value && typeof value === "object") { + cleanOverrides[pieceId] = deepClone(value); + } + }); + normalized.overrides.pieces = cleanOverrides; + return normalized; } function getSelectionCounts(card, draft = ensureDraft(card)) { const selection = getRenderableSelection(card, draft); - if (!selection) { - return { total: 0, aiQuestions: 0, aiExamples: 0, keyPoints: 0, recommended: 0, additional: 0 }; - } + const selectedSet = new Set(selection?.selected?.pieces || []); + const selectedSnippetIds = new Set(); + const selectedSectionKeys = new Set(); + + getExamCardSections(card).forEach((section) => { + section.snippets.forEach((snippet) => { + if (snippet.pieces.some((piece) => selectedSet.has(piece.id))) { + selectedSnippetIds.add(snippet.id); + selectedSectionKeys.add(section.key); + } + }); + }); return { - total: - selection.selected.aiQuestions.length + - selection.selected.aiExamples.length + - selection.selected.keyPoints.length + - selection.selected.recommended.length + - selection.selected.additional.length, - aiQuestions: selection.selected.aiQuestions.length, - aiExamples: selection.selected.aiExamples.length, - keyPoints: selection.selected.keyPoints.length, - recommended: selection.selected.recommended.length, - additional: selection.selected.additional.length, + total: selectedSet.size, + snippets: selectedSnippetIds.size, + sections: selectedSectionKeys.size, }; } -function hasRenderableSelection(card, draft = ensureDraft(card)) { - return getSelectionCounts(card, draft).total > 0; +function getSelectedPieceContexts(card, draft = ensureDraft(card)) { + const selection = getRenderableSelection(card, draft); + const selectedSet = new Set(selection?.selected?.pieces || []); + const contexts = []; + + getExamCardSections(card).forEach((section) => { + section.snippets.forEach((snippet) => { + snippet.pieces.forEach((piece) => { + if (selectedSet.has(piece.id)) { + contexts.push({ section, snippet, piece }); + } + }); + }); + }); + + return contexts; } function getSelectedPreviewEntries() { - return state.cards + return sortTopicCards(state.cards) .map((card) => { - const draft = ensureDraft(card); - const selection = getRenderableSelection(card, draft); - return selection ? { card, selection } : null; - }) - .filter(Boolean) - .sort((a, b) => { - const hitDelta = (b.card.exam_stats?.total_hits || 0) - (a.card.exam_stats?.total_hits || 0); - if (hitDelta !== 0) { - return hitDelta; + const selection = getRenderableSelection(card, ensureDraft(card)); + if (!selection?.selected?.pieces?.length) { + return null; } - return humanizeTopic(a.card.topic).localeCompare(humanizeTopic(b.card.topic)); - }); + return { card, selection }; + }) + .filter(Boolean); } -function getSelectedItemTotals(cards = state.cards) { - return cards.reduce( - (acc, card) => { - const counts = getSelectionCounts(card); - acc.topics += counts.total > 0 ? 1 : 0; - acc.items += counts.total; - return acc; - }, - { topics: 0, items: 0 } - ); +function getSelectedItemTotals() { + const entries = getSelectedPreviewEntries(); + return { + topics: entries.length, + items: entries.reduce((sum, entry) => sum + (entry.selection.selected.pieces || []).length, 0), + }; +} + +function getSectionSelectedCount(card, draft, sectionKey) { + const selection = getRenderableSelection(card, draft); + const selectedSet = new Set(selection?.selected?.pieces || []); + return getSectionSelectablePieceIds(card, sectionKey).filter((pieceId) => selectedSet.has(pieceId)).length; +} + +function getSnippetSelectedCount(card, draft, snippetId) { + const selection = getRenderableSelection(card, draft); + const selectedSet = new Set(selection?.selected?.pieces || []); + return getSnippetSelectablePieceIds(card, snippetId).filter((pieceId) => selectedSet.has(pieceId)).length; } -function getWeekSelectionSummary(bundle) { - return (bundle.cards || []).reduce( - (acc, card) => { - const count = getSelectionCounts(card).total; - acc.topics += count > 0 ? 1 : 0; - acc.items += count; - return acc; +function getPieceOverride(selection, piece) { + const overrides = ensureSelectionOverrides(selection); + const value = overrides.pieces[piece.id]; + if (!value || typeof value !== "object") { + return piece; + } + return { + ...piece, + title: typeof value.title === "string" && value.title.trim() ? value.title.trim() : piece.title, + content: { + ...(piece.content || {}), + ...(value.content && typeof value.content === "object" ? value.content : {}), }, - { topics: 0, items: 0 } - ); + }; +} + +function isPastExamSnippet(snippet) { + return snippet?.snippetType === "past_exam_question"; +} + +function sectionNeedsShowMore(section, draft) { + return section.snippets.length > section.initialVisibleCount && !draft.ui.expandedSections?.[section.key]; } diff --git a/app/view-and-data.js b/app/view-and-data.js index ec8bb6b..f1dfb67 100644 --- a/app/view-and-data.js +++ b/app/view-and-data.js @@ -16,11 +16,7 @@ function toggleDrawer(name) { } function closeDrawers() { - Object.values(drawerMap).forEach((drawer) => { - if (drawer) { - drawer.classList.add("hidden"); - } - }); + Object.values(drawerMap).forEach((drawer) => drawer?.classList.add("hidden")); refs.drawerBackdrop.classList.add("hidden"); state.openDrawer = ""; } @@ -63,54 +59,35 @@ function getFilteredDeck() { return state.cards.filter(cardMatchesFilters); } -function getCardWeek(card) { - const explicitWeek = Number(card?.topic_meta?.week); - if (Number.isFinite(explicitWeek) && explicitWeek > 0) { - return explicitWeek; - } - const fallbackWeek = Number((card?.weeks || [])[0]); - return Number.isFinite(fallbackWeek) && fallbackWeek > 0 ? fallbackWeek : CANONICAL_WEEK_ORDER[0]; -} - function sortTopicCards(cards) { return [...cards].sort((a, b) => { const orderDelta = Number(a?.topic_meta?.topic_order || 0) - Number(b?.topic_meta?.topic_order || 0); if (orderDelta !== 0) { return orderDelta; } - const hitDelta = (b.exam_stats?.total_hits || 0) - (a.exam_stats?.total_hits || 0); - if (hitDelta !== 0) { - return hitDelta; - } return humanizeTopic(a.topic).localeCompare(humanizeTopic(b.topic)); }); } function cardMatchesFilters(card) { - const search = state.filters.search; - const week = getCardWeek(card); - - if (state.filters.onlyExam && card.exam_stats.total_hits === 0) { - return false; - } - - if (card.exam_stats.total_hits < state.filters.minHits) { - return false; - } - - if (state.filters.weeks.size > 0 && !state.filters.weeks.has(week)) { - return false; + if (state.filters.weeks.size > 0) { + const cardWeeks = Array.isArray(card.weeks) ? card.weeks : []; + if (!cardWeeks.some((week) => state.filters.weeks.has(week))) { + return false; + } } + const search = state.filters.search; if (!search) { return true; } const haystack = [ card.topic, - card.canonical_topic, - ...(card.related_topics || []), - ...(card.trap_patterns || []).map((trap) => trap.pattern), + card.parent_topic, + card.summary, + card.search_text, + ...getExamCardSections(card).flatMap((section) => section.snippets.map((snippet) => snippet.title)), ] .join(" ") .toLowerCase(); @@ -118,84 +95,32 @@ function cardMatchesFilters(card) { return haystack.includes(search); } -function getCanonicalWeekOrder() { - if (Array.isArray(state.deckGroups) && state.deckGroups.length > 0) { - const weeks = state.deckGroups - .map((group) => Number(group?.week)) - .filter((week, index, all) => Number.isFinite(week) && !all.slice(0, index).includes(week)); - if (weeks.length) { - return weeks; - } - } - return Array.isArray(CANONICAL_WEEK_ORDER) ? [...CANONICAL_WEEK_ORDER] : [1, 2, 3, 4, 5, 6]; -} +function getFilteredParentBundles() { + const filteredCards = sortTopicCards(getFilteredDeck()); + const byParent = new Map(); -function getWeekCardsForWeek(week, cards = getFilteredDeck()) { - const weekNumber = Number(week); - return sortTopicCards(cards.filter((card) => getCardWeek(card) === weekNumber)); -} + filteredCards.forEach((card) => { + if (!byParent.has(card.parent_topic_id)) { + const source = state.parentTopics.find((parentTopic) => parentTopic.id === card.parent_topic_id); + byParent.set(card.parent_topic_id, { + id: card.parent_topic_id, + title: source?.title || card.parent_topic, + summary: source?.summary || "", + cards: [], + }); + } + byParent.get(card.parent_topic_id).cards.push(card); + }); -function getFilteredWeekBundles() { - const filteredCards = getFilteredDeck(); - const filteredCardById = new Map(filteredCards.map((card) => [card.id, card])); - const sourceBundles = Array.isArray(state.deckGroups) && state.deckGroups.length - ? state.deckGroups - : getCanonicalWeekOrder().map((week) => ({ - id: `week-${week}`, - week, - title: `Week ${week}`, - topic_groups: [ - { - id: `week-${week}-topics`, - title: "Topics", - shortTitle: "Topics", - is_default: true, - topic_refs: getWeekCardsForWeek(week, filteredCards).map((card) => ({ - card_id: card.id, - topic: card.topic, - exam_hits: card.exam_stats?.total_hits || 0, - topic_order: card.topic_meta?.topic_order || 0, - })), - }, - ], - })); - - return sourceBundles - .map((bundle) => { - const groups = (bundle.topic_groups || []) - .map((group) => { - const cards = sortTopicCards( - (group.topic_refs || []) - .map((ref) => filteredCardById.get(ref.card_id)) - .filter(Boolean) - ); - - return { - id: group.id, - title: group.title, - shortTitle: group.shortTitle || group.title, - isDefault: Boolean(group.is_default), - cards, - }; - }) - .filter((group) => group.cards.length > 0); - - return { - id: bundle.id, - title: bundle.title, - week: Number(bundle.week), - groups, - cards: groups.flatMap((group) => group.cards), - }; - }) - .filter((bundle) => Number.isFinite(bundle.week) && bundle.cards.length > 0); + return state.parentTopics + .map((parentTopic) => byParent.get(parentTopic.id)) + .filter((parentTopic) => parentTopic && parentTopic.cards.length > 0); } -function ensureExplorerNavigation(filteredWeekBundles = getFilteredWeekBundles()) { - const visibleBundles = filteredWeekBundles.filter((bundle) => Array.isArray(bundle.cards) && bundle.cards.length > 0); - if (!visibleBundles.length) { +function ensureExplorerNavigation(filteredParents = getFilteredParentBundles()) { + if (!filteredParents.length) { + state.navigation.activeParentId = ""; state.navigation.activeTopicId = ""; - state.navigation.activeWeek = CANONICAL_WEEK_ORDER[0]; return null; } @@ -203,51 +128,55 @@ function ensureExplorerNavigation(filteredWeekBundles = getFilteredWeekBundles() state.navigation = buildDefaultNavigationState(); } - const visibleCardIds = new Set(visibleBundles.flatMap((bundle) => bundle.cards.map((card) => card.id))); - const currentTopicId = String(state.navigation.activeTopicId || "").trim(); - const activeTopicId = visibleCardIds.has(currentTopicId) ? currentTopicId : visibleBundles[0].cards[0].id; - const activeBundle = - visibleBundles.find((bundle) => bundle.cards.some((card) => card.id === activeTopicId)) || visibleBundles[0]; - const activeGroup = - activeBundle.groups?.find((group) => group.cards.some((card) => card.id === activeTopicId)) || activeBundle.groups?.[0] || null; + filteredParents.forEach((parentTopic, index) => { + if (typeof state.navigation.expandedParents[parentTopic.id] !== "boolean") { + state.navigation.expandedParents[parentTopic.id] = index === 0; + } + }); - state.navigation.activeTopicId = activeTopicId; - state.navigation.activeWeek = activeBundle.week; + const visibleCardIds = new Set(filteredParents.flatMap((parentTopic) => parentTopic.cards.map((card) => card.id))); + const currentTopicId = String(state.navigation.activeTopicId || "").trim(); + const activeTopicId = visibleCardIds.has(currentTopicId) ? currentTopicId : filteredParents[0].cards[0].id; + const activeParent = + filteredParents.find((parentTopic) => parentTopic.cards.some((card) => card.id === activeTopicId)) || filteredParents[0]; + const activeCard = activeParent.cards.find((card) => card.id === activeTopicId) || activeParent.cards[0]; - if (!state.navigation.expandedWeeks || typeof state.navigation.expandedWeeks !== "object") { - state.navigation.expandedWeeks = Object.fromEntries(CANONICAL_WEEK_ORDER.map((week) => [String(week), true])); - } - if (!Object.values(state.navigation.expandedWeeks).some(Boolean)) { - state.navigation.expandedWeeks[String(activeBundle.week)] = true; - } - if (!state.navigation.expandedWeeks[String(activeBundle.week)]) { - state.navigation.expandedWeeks[String(activeBundle.week)] = true; - } + state.navigation.activeTopicId = activeCard.id; + state.navigation.activeParentId = activeParent.id; + state.navigation.expandedParents[activeParent.id] = true; - return { - bundle: activeBundle, - group: activeGroup, - card: activeBundle.cards.find((card) => card.id === activeTopicId) || activeBundle.cards[0], - }; + return { parentTopic: activeParent, card: activeCard }; } -function setActiveTopic(cardId, week) { +function setActiveTopic(cardId, parentId) { if (!cardId) { return; } state.navigation.activeTopicId = cardId; - if (Number.isFinite(Number(week))) { - state.navigation.activeWeek = Number(week); - state.navigation.expandedWeeks[String(week)] = true; + state.navigation.activeParentId = parentId || state.navigation.activeParentId; + if (parentId) { + state.navigation.expandedParents[parentId] = true; } state.navigation.mobileSidebarOpen = false; renderSwipe(); schedulePersistState(); } -function toggleWeekExpanded(week) { - const key = String(week); - state.navigation.expandedWeeks[key] = !Boolean(state.navigation.expandedWeeks[key]); +function toggleParentExpanded(parentId) { + if (!parentId) { + return; + } + state.navigation.expandedParents[parentId] = !Boolean(state.navigation.expandedParents[parentId]); renderSwipe(); schedulePersistState(); } + +function getParentSelectionSummary(parentTopic) { + const cards = Array.isArray(parentTopic?.cards) ? parentTopic.cards : []; + const selectedTopics = cards.filter((card) => getSelectionCounts(card).total > 0).length; + const selectedItems = cards.reduce((sum, card) => sum + getSelectionCounts(card).total, 0); + return { + topics: selectedTopics, + items: selectedItems, + }; +} diff --git a/data/exam_builder_topics.json b/data/exam_builder_topics.json new file mode 100644 index 0000000..777aaeb --- /dev/null +++ b/data/exam_builder_topics.json @@ -0,0 +1,7975 @@ +{ + "schema_version": "2026-03-24-manual-curation-v1", + "generated_at": "2026-03-24", + "meta": { + "authoring_mode": "agent-authored manual curation", + "source_draft_dir": "data/manual_curation_drafts" + }, + "parent_topics": [ + { + "id": "python-foundations", + "title": "Python Foundations", + "summary": "Core syntax, name/object reasoning, operator logic, and condition-building rules that recur across the early-course exams. This manual draft keeps only dense, exam-useful material and removes noisy cross-topic spillover from the generated intake.", + "source_refs": { + "draft_file": "python_foundations.json" + }, + "main_topics": [ + { + "id": "python-basics", + "title": "Python Basics", + "summary": "Read code literally: know what Python ignores, how one statement can span lines, and which backslashes do or do not create escapes.", + "parent_topic": "Python Foundations", + "main_week": 1, + "related_weeks": [ + 1 + ], + "topic_order": 1, + "search_text": "Python Basics Read code literally: know what Python ignores, how one statement can span lines, and which backslashes do or do not create escapes. Comments, Logical Lines, and Raw Strings Most beginner syntax mistakes here come from forgetting what `#` ignores, when Python allows line continuation, and how raw strings treat backslashes. Escape Sequences and Quote Choices Keep one tiny reference for newline, tab, backslash, and quote escaping so you do not have to reconstruct them from memory in a syntax question. Read Tiny Syntax Fragments Literally Week-1 basics questions are often solved by tracing exactly what Python reads, not by overthinking intent. Execution Precision Mental Model Useful as a fallback reminder when two syntax options look similar.", + "source_refs": { + "topic_card_id": "w1-python-basics", + "exam_builder_topic_id": "python-basics" + }, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "python-basics-syntax-rules", + "title": "Comments, Logical Lines, and Raw Strings", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Python Basics", + "summary": "Most beginner syntax mistakes here come from forgetting what `#` ignores, when Python allows line continuation, and how raw strings treat backslashes.", + "source_refs": [ + { + "exam_builder_snippet_ids": [ + "snippet-subtopic-w1-python-basics-w1-python-basics-execution-model", + "snippet-item-manual-comments", + "snippet-item-manual-logical-lines" + ], + "topic_card_piece_ids": [ + "manual-comments", + "manual-logical-lines", + "ai-example-4", + "ai-example-5", + "ai-example-6" + ] + } + ], + "pieces": [ + { + "id": "python-basics-syntax-rules-table", + "piece_type": "reference_table", + "title": "Syntax rules you should recall instantly", + "order": 1, + "content": { + "text": "", + "headers": [ + "Pattern", + "What Python does", + "Example" + ], + "rows": [ + [ + "# comment", + "ignores everything after `#` on that logical line", + "x = 3 # ignored text" + ], + [ + "open brackets", + "statement can continue on later physical lines", + "nums = [\\n 1,\\n 2\\n]" + ], + [ + "backslash `\\\\`", + "explicitly continues one statement onto the next line", + "a = 'hi' + \\\\\\n ' there'" + ], + [ + "raw string `r'...'`", + "backslashes are kept literally; quotes still must match", + "r'c:\\\\temp\\\\file.txt'" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "manual-comments", + "manual-logical-lines", + "ai-example-4", + "ai-example-5", + "ai-example-6" + ] + } + ] + }, + { + "id": "python-basics-syntax-rules-code", + "piece_type": "code_example", + "title": "Compact syntax examples", + "order": 2, + "content": { + "text": "Use brackets whenever possible; use an explicit backslash only when there is no bracketed structure to hold the continuation.", + "code": "x = 3 # comment does not execute\nprint(x)\n\npath = r'c:\\\new\\\\folder'\n\nnumbers = [\n 1,\n 2,\n 3,\n]", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "manual-comments", + "manual-logical-lines", + "ai-example-4" + ] + } + ] + } + ] + }, + { + "id": "python-basics-escape-sequences", + "title": "Escape Sequences and Quote Choices", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Python Basics", + "summary": "Keep one tiny reference for newline, tab, backslash, and quote escaping so you do not have to reconstruct them from memory in a syntax question.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "ai-example-4", + "ai-example-7", + "manual-string-literals-example" + ] + } + ], + "pieces": [ + { + "id": "python-basics-escape-sequences-table", + "piece_type": "reference_table", + "title": "Small escapes worth recognizing instantly", + "order": 1, + "content": { + "text": "This is intentionally tiny: it is here for exact syntax and output questions, not for prose explanation.", + "headers": [ + "Pattern", + "Meaning", + "Example output" + ], + "rows": [ + [ + "\\n", + "newline", + "Line 1 then Line 2 on the next line" + ], + [ + "\\t", + "tab", + "horizontal spacing" + ], + [ + "\\\\", + "literal backslash", + "c:\\\\new\\\\folder" + ], + [ + "quote escape", + "literal quote inside a string", + "use the other quote style or escape it" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ai-example-4", + "ai-example-7", + "manual-string-literals-example" + ] + } + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "python-basics-read-it-literally", + "title": "Read Tiny Syntax Fragments Literally", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Python Basics", + "summary": "Week-1 basics questions are often solved by tracing exactly what Python reads, not by overthinking intent.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "cs-09e2b215ee", + "cs-7498cfc507", + "cs-814a07a136" + ] + } + ], + "pieces": [ + { + "id": "python-basics-read-it-literally-code", + "piece_type": "code_example", + "title": "Literal reading beats guessing", + "order": 1, + "content": { + "text": "If Python sees a valid literal expression, it evaluates that expression only. Ignore the story in your head and trace the actual tokens.", + "code": "print('Hello World') # prints only Hello World\n# print(_, __, ___) -> the whole line is a comment if it starts with #\n123 * 1 # plain arithmetic, no hidden meaning", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "cs-09e2b215ee", + "cs-7498cfc507", + "cs-814a07a136" + ] + } + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "python-basics-execution-model", + "title": "Execution Precision Mental Model", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Python Basics", + "summary": "Useful as a fallback reminder when two syntax options look similar.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "kp-1", + "ks-95be7f9418" + ] + } + ], + "pieces": [ + { + "id": "python-basics-execution-model-text", + "piece_type": "explanation", + "title": "Python is precise, not forgiving", + "order": 1, + "content": { + "text": "Python translates your script step by step, so tiny syntax differences matter. If two options look almost the same, assume Python will care about the exact tokens, indentation, and delimiters." + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-1", + "ks-95be7f9418" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "objects-and-names", + "title": "Objects and Names", + "summary": "Know what a name points to, which objects can change in place, and when code is creating a new object versus sharing the old one.", + "parent_topic": "Python Foundations", + "main_week": 1, + "related_weeks": [ + 1, + 2 + ], + "topic_order": 2, + "search_text": "Objects and Names Know what a name points to, which objects can change in place, and when code is creating a new object versus sharing the old one. Names Bind to Objects This is the main mental model: names point at objects; rebinding changes the name-object link, while mutation changes a mutable object in place. Mutable, Immutable, and Copying Many exam traps reduce to three questions: is the object mutable, are two names sharing it, and did slicing create a copy? Trace Slices and Indexed Assignment Carefully These questions are usually about excluded stop values, negative indices, or using values as indices by mistake. Mutable Default Argument Trap A default list or dict is created once when the function is defined, not each time the function is called. Core Types and Naming Rules Low-friction reference material for early exam questions.", + "source_refs": { + "topic_card_id": "w1-objects-and-names", + "exam_builder_topic_id": "objects-and-names" + }, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "objects-and-names-binding", + "title": "Names Bind to Objects", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Objects and Names", + "summary": "This is the main mental model: names point at objects; rebinding changes the name-object link, while mutation changes a mutable object in place.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "kp-1", + "kp-3", + "kp-9" + ] + } + ], + "pieces": [ + { + "id": "objects-and-names-binding-table", + "piece_type": "reference_table", + "title": "What changes in each case?", + "order": 1, + "content": { + "text": "", + "headers": [ + "Action", + "Effect", + "Example" + ], + "rows": [ + [ + "rebind a name", + "name points to a different object", + "x = 3; x = '3'" + ], + [ + "mutate a list/dict/set", + "same object, changed contents", + "lst[0] = 99" + ], + [ + "call a method on an immutable value", + "usually returns a new object; original stays unchanged", + "s = 'abc'; s.upper()" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-1", + "kp-3", + "aiq-2" + ] + } + ] + }, + { + "id": "objects-and-names-binding-code", + "piece_type": "code_example", + "title": "Rebinding versus mutation", + "order": 2, + "content": { + "text": "Lists are mutable; strings are not. A method call on a string does not update the original variable unless you reassign.", + "code": "name = [1, 2, 3]\nalias = name\nname[0] = 99\nprint(alias) # [99, 2, 3]\n\ns = 'abc'\ns.upper()\nprint(s) # 'abc' (unchanged)", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-2", + "kp-manual-aliasing-copy", + "aiq-2" + ] + } + ] + } + ] + }, + { + "id": "objects-and-names-mutable-vs-immutable", + "title": "Mutable, Immutable, and Copying", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Objects and Names", + "summary": "Many exam traps reduce to three questions: is the object mutable, are two names sharing it, and did slicing create a copy?", + "source_refs": [ + { + "topic_card_piece_ids": [ + "kp-2", + "kp-6", + "kp-manual-aliasing-copy" + ] + } + ], + "pieces": [ + { + "id": "objects-and-names-mutable-vs-immutable-table", + "piece_type": "reference_table", + "title": "Fast mutability check", + "order": 1, + "content": { + "text": "", + "headers": [ + "Type", + "Mutable?", + "Typical trap" + ], + "rows": [ + [ + "int, float, str, tuple", + "no", + "operation gives a new value/object" + ], + [ + "list, dict, set", + "yes", + "an alias sees in-place changes" + ], + [ + "slice `seq[:]`", + "new object", + "copy of the outer sequence" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-2", + "kp-6", + "kp-manual-aliasing-copy" + ] + } + ] + }, + { + "id": "objects-and-names-mutable-vs-immutable-code", + "piece_type": "code_example", + "title": "Aliasing versus slicing copy", + "order": 2, + "content": { + "text": "`l2 = l1` shares the same list. `l1[:]` creates a new outer list.", + "code": "l1 = [1, 2, 3]\nl2 = l1\nl3 = l1[:]\nl1[0] = 99\nprint(l2) # [99, 2, 3]\nprint(l3) # [1, 2, 3]", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-manual-aliasing-copy-d1", + "aiq-6" + ] + } + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "objects-and-names-slicing-and-range-trace", + "title": "Trace Slices and Indexed Assignment Carefully", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Objects and Names", + "summary": "These questions are usually about excluded stop values, negative indices, or using values as indices by mistake.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "aiq-3", + "kp-6-d1", + "kp-6-d2" + ] + } + ], + "pieces": [ + { + "id": "objects-and-names-slicing-and-range-trace-text", + "piece_type": "explanation", + "title": "Three rules that resolve most slice questions", + "order": 1, + "content": { + "text": "For `seq[start:end:step]`, start is included, end is excluded, and a negative step walks right-to-left. When squaring list elements with a loop over indices, use `range(len(x))`, not the element values themselves." + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "aiq-3", + "kp-6" + ] + } + ] + }, + { + "id": "objects-and-names-slicing-and-range-trace-code", + "piece_type": "code_example", + "title": "Correct index-based update pattern", + "order": 2, + "content": { + "text": "Looping with `for i in x` gives element values, not safe positions.", + "code": "mylist = [0] * len(x)\nfor i in range(len(x)):\n mylist[i] = x[i] ** 2", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "aiq-3" + ] + } + ] + } + ] + }, + { + "id": "objects-and-names-mutable-defaults", + "title": "Mutable Default Argument Trap", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Objects and Names", + "summary": "A default list or dict is created once when the function is defined, not each time the function is called.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "aiq-7" + ] + } + ], + "pieces": [ + { + "id": "objects-and-names-mutable-defaults-code", + "piece_type": "code_example", + "title": "Use `None`, then create the object inside", + "order": 1, + "content": { + "text": "This avoids sharing one default list across multiple calls.", + "code": "def f(lst=None):\n if lst is None:\n lst = []\n return lst", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "aiq-7" + ] + } + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "objects-and-names-builtins-and-naming", + "title": "Core Types and Naming Rules", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Objects and Names", + "summary": "Low-friction reference material for early exam questions.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "kp-4", + "kp-5" + ] + } + ], + "pieces": [ + { + "id": "objects-and-names-builtins-and-naming-table", + "piece_type": "reference_table", + "title": "Built-in types and name rules", + "order": 1, + "content": { + "text": "", + "headers": [ + "Thing", + "Remember" + ], + "rows": [ + [ + "core types", + "`int`, `float`, `str`, `bool`, `tuple`, `list`, `dict`, `set`" + ], + [ + "valid names", + "letters, digits, underscores; cannot start with a digit" + ], + [ + "case sensitivity", + "`name` and `Name` are different" + ], + [ + "avoid shadowing", + "do not reuse names like `list`, `print`, `sorted`" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-4", + "kp-5" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "operators-and-truth", + "title": "Operators and Truth", + "summary": "Arithmetic, comparisons, and boolean logic questions are mostly about operator meaning, precedence, and a few recurring traps.", + "parent_topic": "Python Foundations", + "main_week": 1, + "related_weeks": [ + 1, + 2 + ], + "topic_order": 3, + "search_text": "Operators and Truth Arithmetic, comparisons, and boolean logic questions are mostly about operator meaning, precedence, and a few recurring traps. Arithmetic Operator Reference The highest-yield early-operator facts are `/` vs `//`, `%`, `**`, and the reminder that `^` is not exponentiation. Comparison and Boolean Logic Comparison operators return booleans, and precedence is a common exam trap. Negative Floor-Division and Modulo This exact pattern recurs because students often expect truncation toward zero instead of flooring. Float Precision and Ordered Comparison Traps The exam often mixes one numeric precision surprise with one ordered-versus-unordered comparison surprise. Quick Boolean Reminder Tiny fallback reminder when a condition question becomes a logic puzzle. `==` compares values; `is` compares identity This is a small but classic distractor, especially when two options print the same thing but use different operators.", + "source_refs": { + "topic_card_id": "w1-operators-and-truth", + "exam_builder_topic_id": "operators-and-truth" + }, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "operators-and-truth-arithmetic-reference", + "title": "Arithmetic Operator Reference", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Operators and Truth", + "summary": "The highest-yield early-operator facts are `/` vs `//`, `%`, `**`, and the reminder that `^` is not exponentiation.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "kp-1", + "ai-example-1" + ] + } + ], + "pieces": [ + { + "id": "operators-and-truth-arithmetic-reference-table", + "piece_type": "reference_table", + "title": "Arithmetic operators at a glance", + "order": 1, + "content": { + "text": "", + "headers": [ + "Operator", + "Meaning", + "Example" + ], + "rows": [ + [ + "/", + "true division, returns float", + "4 / 2 -> 2.0" + ], + [ + "//", + "floor division", + "5 // 2 -> 2" + ], + [ + "%", + "remainder", + "5 % 2 -> 1" + ], + [ + "**", + "exponentiation", + "4 ** 3 -> 64" + ], + [ + "^", + "bitwise XOR, not power", + "do not use for exponentiation" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-1" + ] + } + ] + }, + { + "id": "operators-and-truth-arithmetic-reference-code", + "piece_type": "code_example", + "title": "Floor division and modulo identity", + "order": 2, + "content": { + "text": "This identity is reliable even when negative numbers make the floor result look surprising.", + "code": "print(5 // 3, 5 % 3)\nprint(-5 // 3, -5 % 3)\n# (a // b) * b + a % b == a", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ai-example-1" + ] + } + ] + } + ] + }, + { + "id": "operators-and-truth-comparison-and-logic", + "title": "Comparison and Boolean Logic", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Operators and Truth", + "summary": "Comparison operators return booleans, and precedence is a common exam trap.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "kp-2", + "kp-3", + "ai-example-4", + "ai-example-8" + ] + } + ], + "pieces": [ + { + "id": "operators-and-truth-comparison-and-logic-table", + "piece_type": "reference_table", + "title": "Comparison and logic rules", + "order": 1, + "content": { + "text": "", + "headers": [ + "Rule", + "Remember" + ], + "rows": [ + [ + "comparison result", + "`==`, `!=`, `<`, `>`, `<=`, `>=` always produce `True` or `False`" + ], + [ + "`==` vs `is`", + "`==` compares value; `is` compares object identity" + ], + [ + "precedence", + "`not` before `and`, and `and` before `or`" + ], + [ + "safe habit", + "add parentheses when the intended grouping is not obvious" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-2", + "kp-3", + "ai-example-8" + ] + } + ] + }, + { + "id": "operators-and-truth-comparison-and-logic-code", + "piece_type": "code_example", + "title": "Precedence trap", + "order": 2, + "content": { + "text": "The first line is parsed as `a == 1 or (a == 2 and b == 1) or b == 2`.", + "code": "a = 1; b = 3\nprint(a == 1 or a == 2 and b == 1 or b == 2)\nprint((a == 1 or a == 2) and (b == 1 or b == 2))", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ai-example-4" + ] + } + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "operators-and-truth-negative-floor-division", + "title": "Negative Floor-Division and Modulo", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Operators and Truth", + "summary": "This exact pattern recurs because students often expect truncation toward zero instead of flooring.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "ai-example-1", + "cs-266616a010" + ] + } + ], + "pieces": [ + { + "id": "operators-and-truth-negative-floor-division-code", + "piece_type": "code_example", + "title": "Outputs with negative numerators", + "order": 1, + "content": { + "text": "`//` rounds down to the next lower integer, so it can be smaller than simple truncation.", + "code": "print(-5 // 3, -5 % 3) # -2 1\nprint(-5 // 2, -5 % 2) # -3 1", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ai-example-1", + "cs-266616a010" + ] + } + ] + } + ] + }, + { + "id": "operators-and-truth-float-and-sequence-traps", + "title": "Float Precision and Ordered Comparison Traps", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Operators and Truth", + "summary": "The exam often mixes one numeric precision surprise with one ordered-versus-unordered comparison surprise.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "ai-example-2", + "ai-example-3" + ] + } + ], + "pieces": [ + { + "id": "operators-and-truth-float-and-sequence-traps-code", + "piece_type": "code_example", + "title": "Two classic comparison pitfalls", + "order": 1, + "content": { + "text": "Lists/tuples/strings are ordered. Sets and dict equality ignore insertion order.", + "code": "print(1.1 + 2.2 == 3.3) # False\nprint([1, 2] == [2, 1]) # False\nprint({1, 2} == {2, 1}) # True", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ai-example-2", + "ai-example-3" + ] + } + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "operators-and-truth-quick-boolean-reminder", + "title": "Quick Boolean Reminder", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Operators and Truth", + "summary": "Tiny fallback reminder when a condition question becomes a logic puzzle.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "kp-3" + ] + } + ], + "pieces": [ + { + "id": "operators-and-truth-quick-boolean-reminder-text", + "piece_type": "explanation", + "title": "`and`, `or`, `not` in one line", + "order": 1, + "content": { + "text": "`x and y` is true only if both are true. `x or y` is false only if both are false. `not x` flips a boolean." + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "kp-3" + ] + } + ] + } + ] + }, + { + "id": "operators-and-truth-equality-vs-identity", + "title": "`==` compares values; `is` compares identity", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Operators and Truth", + "summary": "This is a small but classic distractor, especially when two options print the same thing but use different operators.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "ai-example-8", + "kp-2" + ] + } + ], + "pieces": [ + { + "id": "operators-and-truth-equality-vs-identity-table", + "piece_type": "reference_table", + "title": "Value test versus identity test", + "order": 1, + "content": { + "text": "If the exam is not specifically about object identity, `==` is usually the intended operator.", + "headers": [ + "Expression", + "Checks", + "Use it for" + ], + "rows": [ + [ + "a == b", + "same value", + "normal equality questions" + ], + [ + "a is b", + "same object in memory", + "identity / None checks" + ], + [ + "x is None", + "identity to the singleton None", + "preferred None check" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ai-example-8", + "kp-2" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "conditions", + "title": "Conditions", + "summary": "Condition questions usually test three things: how branching syntax is structured, how truthiness and membership work, and whether compound logic is grouped correctly.", + "parent_topic": "Python Foundations", + "main_week": 2, + "related_weeks": [ + 2, + 3 + ], + "topic_order": 4, + "search_text": "Conditions Condition questions usually test three things: how branching syntax is structured, how truthiness and membership work, and whether compound logic is grouped correctly. if / elif / else and Ternary Expressions Know when to use a full branch block and when a single conditional expression is enough. Truthiness and `in` A lot of conditions can be solved by knowing which values are falsy and what membership tests actually check. Parenthesize Compound Conditions A frequent exam pattern is that the unparenthesized condition is legal Python but means something different from what students intended. Filter by Applying the Condition to Each Element When a function accepts a `condition`, trace one element first and keep the elements where the condition returns `True`. Convert Before Comparing Mixed Types Useful backup for conditions that mix strings, ints, floats, and booleans.", + "source_refs": { + "topic_card_id": "w2-conditions", + "exam_builder_topic_id": "conditions" + }, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "conditions-branching-and-ternary", + "title": "if / elif / else and Ternary Expressions", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Conditions", + "summary": "Know when to use a full branch block and when a single conditional expression is enough.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "ks-c19999c074", + "manual-conditional-expression", + "kp-manual-ternary" + ] + } + ], + "pieces": [ + { + "id": "conditions-branching-and-ternary-table", + "piece_type": "reference_table", + "title": "Branching choices", + "order": 1, + "content": { + "text": "", + "headers": [ + "Form", + "Use it when", + "Example" + ], + "rows": [ + [ + "if / elif / else", + "branches need statements or multiple actions", + "full block with indentation" + ], + [ + "x if cond else y", + "you only need one resulting value", + "label = 'pass' if score >= 10 else 'fail'" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ks-c19999c074", + "manual-conditional-expression", + "kp-manual-ternary" + ] + } + ] + }, + { + "id": "conditions-branching-and-ternary-code", + "piece_type": "code_example", + "title": "Block form versus expression form", + "order": 2, + "content": { + "text": "Keep the full indented skeleton in mind for branch questions; use the ternary form only when one value is chosen.", + "code": "if score >= 18:\n label = 'excellent'\nelif score >= 10:\n label = 'pass'\nelse:\n label = 'fail'\n\nshort_label = 'pass' if score >= 10 else 'fail'", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "manual-conditional-expression", + "ks-c19999c074" + ] + } + ] + } + ] + }, + { + "id": "conditions-truthiness-and-membership", + "title": "Truthiness and `in`", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Conditions", + "summary": "A lot of conditions can be solved by knowing which values are falsy and what membership tests actually check.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core", + "ks-4b427a2425" + ] + } + ], + "pieces": [ + { + "id": "conditions-truthiness-and-membership-table", + "piece_type": "reference_table", + "title": "Truthy/falsy and membership rules", + "order": 1, + "content": { + "text": "", + "headers": [ + "Pattern", + "Result", + "Remember" + ], + "rows": [ + [ + "[], (), {}, set(), '', 0, 0.0, None", + "falsy", + "empty/zero values fail a condition" + ], + [ + "non-empty collection / non-zero number", + "truthy", + "passes a condition" + ], + [ + "key in dict", + "checks keys", + "`4 in {1:4, 2:3}` is False" + ], + [ + "'1' in '123'", + "substring test", + "works on strings too" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ks-4b427a2425", + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core" + ] + } + ] + }, + { + "id": "conditions-truthiness-and-membership-code", + "piece_type": "code_example", + "title": "`in` examples worth memorizing", + "order": 2, + "content": { + "text": "For dictionaries, membership tests keys, not values.", + "code": "print(1 in [1, 2, 3]) # True\nprint('1' in '123') # True\nprint(1 in {1: 4, 2: 3}) # True\nprint(4 in {1: 4, 2: 3}) # False", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "ks-4b427a2425" + ] + } + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "conditions-precedence-trap", + "title": "Parenthesize Compound Conditions", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Conditions", + "summary": "A frequent exam pattern is that the unparenthesized condition is legal Python but means something different from what students intended.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "manual-bool-precedence", + "kp-manual-precedence", + "ai-example-1" + ] + } + ], + "pieces": [ + { + "id": "conditions-precedence-trap-code", + "piece_type": "code_example", + "title": "The classic precedence trap", + "order": 1, + "content": { + "text": "If the logic matters, parenthesize. Do not rely on memory under exam pressure.", + "code": "a = 1; b = 3\nprint(a == 1 or a == 2 and b == 1 or b == 2)\nprint((a == 1 or a == 2) and (b == 1 or b == 2))", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "manual-bool-precedence", + "kp-manual-precedence", + "ai-example-1" + ] + } + ] + } + ] + }, + { + "id": "conditions-filtering-pattern", + "title": "Filter by Applying the Condition to Each Element", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Conditions", + "summary": "When a function accepts a `condition`, trace one element first and keep the elements where the condition returns `True`.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "manual-filter-condition", + "exam-trial_midterm-6-w2-conditions" + ] + } + ], + "pieces": [ + { + "id": "conditions-filtering-pattern-code", + "piece_type": "code_example", + "title": "Condition-driven filtering", + "order": 1, + "content": { + "text": "The lambda keeps odd values here because `x % 2 != 0` is true only for odd numbers.", + "code": "def main(lst, condition):\n return [x for x in lst if condition(x)]\n\nmain([1, 2, 3, 4], lambda x: x % 2 != 0) # [1, 3]", + "output": "" + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "manual-filter-condition", + "exam-trial_midterm-6-w2-conditions" + ] + } + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "conditions-explicit-conversion", + "title": "Convert Before Comparing Mixed Types", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Python Foundations", + "main_topic": "Conditions", + "summary": "Useful backup for conditions that mix strings, ints, floats, and booleans.", + "source_refs": [ + { + "topic_card_piece_ids": [ + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core", + "exam-midterm_2024-2-w2-conditions" + ] + } + ], + "pieces": [ + { + "id": "conditions-explicit-conversion-table", + "piece_type": "reference_table", + "title": "Common conversions and traps", + "order": 1, + "content": { + "text": "", + "headers": [ + "Goal", + "Do this", + "Trap" + ], + "rows": [ + [ + "string to int", + "`int('3')`", + "`'3' == 3` is false because the types differ" + ], + [ + "string to float", + "`float('3.0')`", + "invalid numeric text raises `ValueError`" + ], + [ + "numeric truth", + "`0` is false, non-zero is true", + "`True == 1` and `False == 0` in numeric contexts" + ], + [ + "invalid integer text", + "int('1a')", + "raises `ValueError`" + ], + [ + "mix string and int directly", + "str(1) + \"2\" or int(\"2\") + 1", + "'1' + 2 raises `TypeError`" + ] + ] + }, + "selectable": true, + "source_refs": [ + { + "derived_from": [ + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core", + "exam-midterm_2024-2-w2-conditions" + ] + } + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "collections-and-iteration", + "title": "Collections and Iteration", + "summary": "Lists, sets, dictionaries, loops, and comprehension patterns that help you read Python data flow quickly.", + "source_refs": { + "draft_file": "collections_and_iteration.json" + }, + "main_topics": [ + { + "id": "lists-and-sets", + "title": "Lists and Sets", + "summary": "Indexing, slicing, list mutation, and the key difference between ordered sequences and unordered unique-value sets.", + "parent_topic": "Collections and Iteration", + "main_week": 2, + "related_weeks": [ + 1, + 2 + ], + "topic_order": 5, + "search_text": "Lists and Sets Indexing, slicing, list mutation, and the key difference between ordered sequences and unordered unique-value sets. Indexing, slicing, and range at a glance List operations mutate the list Ordered sequences vs sets Reverse-and-step slicing trap Chunk a list with slicing inside a comprehension Check whether all items are unique Find the nth occurrence of a value Set basics worth remembering Mutating list methods usually return `None` List mutation and set reminders", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "ls-mk-1", + "title": "Indexing, slicing, and range at a glance", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ], + "pieces": [ + { + "id": "ls-mk-1-table", + "piece_type": "reference_table", + "title": "Indexing, slicing, and range at a glance", + "order": 1, + "content": { + "text": "", + "headers": [ + "Pattern", + "Meaning", + "Example result" + ], + "rows": [ + [ + "seq[i]", + "single element at index i", + "['a', 'b', 'c'][1] -> 'b'" + ], + [ + "seq[-1]", + "last element", + "[1, 2, 3][-1] -> 3" + ], + [ + "seq[a:b]", + "start included, stop excluded", + "[1, 2, 3, 4][1:3] -> [2, 3]" + ], + [ + "seq[::2]", + "every second element", + "[1, 2, 3, 4, 5][::2] -> [1, 3, 5]" + ], + [ + "seq[::-1]", + "reversed copy", + "[1, 2, 3][::-1] -> [3, 2, 1]" + ], + [ + "range(start, stop, step)", + "stop is excluded", + "list(range(3, 8, 2)) -> [3, 5, 7]" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + } + ] + }, + { + "id": "ls-mk-2", + "title": "List operations mutate the list", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ], + "pieces": [ + { + "id": "ls-mk-2-code", + "piece_type": "code_example", + "title": "List operations mutate the list", + "order": 1, + "content": { + "text": "Lists are mutable. Read exam code in order and track the updated list after each line.", + "code": "values = [1, 3, 2, 3]\nvalues.append(5) # [1, 3, 2, 3, 5]\nvalues.remove(3) # removes the first 3 only\nprint(values) # [1, 2, 3, 5]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ] + }, + { + "id": "ls-mk-3", + "title": "Ordered sequences vs sets", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ], + "pieces": [ + { + "id": "ls-mk-3-table", + "piece_type": "reference_table", + "title": "Ordered sequences vs sets", + "order": 1, + "content": { + "text": "", + "headers": [ + "Collection", + "Ordered for equality?", + "Duplicates kept?", + "Indexing?" + ], + "rows": [ + [ + "list / tuple / str", + "yes", + "yes", + "yes" + ], + [ + "set", + "no", + "no", + "no" + ], + [ + "dict", + "no for equality", + "keys unique", + "lookup by key, not by position" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "ls-ep-1", + "title": "Reverse-and-step slicing trap", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ], + "pieces": [ + { + "id": "ls-ep-1-code", + "piece_type": "code_example", + "title": "Reverse-and-step slicing trap", + "order": 1, + "content": { + "text": "When a question compares slicing expressions, work left to right. `seq[::2][::-1]` means take every second element first, then reverse that shorter list.", + "code": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nprint(numbers[::2]) # [1, 3, 5, 7, 9]\nprint(numbers[::2][::-1]) # [9, 7, 5, 3, 1]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + } + ] + }, + { + "id": "ls-ep-2", + "title": "Chunk a list with slicing inside a comprehension", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ], + "pieces": [ + { + "id": "ls-ep-2-code", + "piece_type": "code_example", + "title": "Chunk a list with slicing inside a comprehension", + "order": 1, + "content": { + "text": "A common exam pattern is splitting a list into fixed-size sublists.", + "code": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nchunks = [x[i:i + 3] for i in range(0, len(x), 3)]\nprint(chunks)\n# [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + } + ] + }, + { + "id": "ls-ep-3", + "title": "Check whether all items are unique", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ], + "pieces": [ + { + "id": "ls-ep-3-code", + "piece_type": "code_example", + "title": "Check whether all items are unique", + "order": 1, + "content": { + "text": "Turning a sequence into a set removes duplicates, so compare lengths.", + "code": "def all_unique(values):\n return len(values) == len(set(values))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "ls-ub-1", + "title": "Find the nth occurrence of a value", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ], + "pieces": [ + { + "id": "ls-ub-1-code", + "piece_type": "code_example", + "title": "Find the nth occurrence of a value", + "order": 1, + "content": { + "text": "Use `.index(value, start)` repeatedly when the question asks for the second or third occurrence.", + "code": "x = ['A', 'B', 'A', 'C', 'B', 'A', 'B']\nn = 2\ni = -1\nfor _ in range(n):\n i = x.index('B', i + 1)\nprint(i) # 4", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + } + ] + }, + { + "id": "ls-ub-2", + "title": "Set basics worth remembering", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ], + "pieces": [ + { + "id": "ls-ub-2-table", + "piece_type": "reference_table", + "title": "Set basics worth remembering", + "order": 1, + "content": { + "text": "", + "headers": [ + "Pattern", + "Reminder" + ], + "rows": [ + [ + "set()", + "creates an empty set" + ], + [ + "{}", + "creates an empty dict, not a set" + ], + [ + "value in my_set", + "membership works, indexing does not" + ], + [ + "my_set.add(x) / update(xs)", + "mutates the set" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ] + }, + { + "id": "ls-ub-3", + "title": "Mutating list methods usually return `None`", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ], + "pieces": [ + { + "id": "ls-ub-3-table", + "piece_type": "reference_table", + "title": "Mutating list methods usually return `None`", + "order": 1, + "content": { + "text": "This trap crosses over with function-return questions, so it is worth keeping explicitly.", + "headers": [ + "Pattern", + "What happens" + ], + "rows": [ + [ + "values.append(5)", + "list changes in place; expression itself returns `None`" + ], + [ + "values.sort()", + "list is reordered in place; expression itself returns `None`" + ], + [ + "sorted(values)", + "returns a new sorted list" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + }, + { + "id": "ls-ub-3-text", + "piece_type": "explanation", + "title": "Mutating list methods usually return `None`", + "order": 2, + "content": { + "text": "This trap crosses over with function-return questions, so it is worth keeping explicitly." + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ] + } + ] + }, + { + "key": "quick_tables", + "title": "Quick Tables", + "description": "", + "initial_visible_count": 1, + "snippets": [ + { + "id": "ls-qt-1", + "title": "List mutation and set reminders", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Lists and Sets", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ], + "pieces": [ + { + "id": "ls-qt-1-table", + "piece_type": "reference_table", + "title": "List mutation and set reminders", + "order": 1, + "content": { + "text": "These are the list/set reminders that are easiest to miss in short output questions.", + "headers": [ + "Pattern", + "Remember" + ], + "rows": [ + [ + "lst.append(x)", + "adds one item at the end" + ], + [ + "lst.sort()", + "sorts in place and returns None" + ], + [ + "lst.append(x)", + "mutates the list; do not assign its return value" + ], + [ + "lst.remove(x)", + "removes the first matching value" + ], + [ + "lst.pop(i)", + "removes and returns an item" + ], + [ + "set()", + "empty set" + ], + [ + "{}", + "empty dict, not a set" + ], + [ + "x in my_set", + "membership works, indexing does not" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + }, + { + "id": "ls-qt-1-text", + "piece_type": "explanation", + "title": "List mutation and set reminders", + "order": 2, + "content": { + "text": "These are the list/set reminders that are easiest to miss in short output questions." + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ] + } + ] + } + ] + }, + { + "id": "dictionaries-and-mappings", + "title": "Dictionaries and Mappings", + "summary": "Key-based lookup, membership, iteration, and the most common construction patterns.", + "parent_topic": "Collections and Iteration", + "main_week": 2, + "related_weeks": [ + 2, + 6 + ], + "topic_order": 6, + "search_text": "Dictionaries and Mappings Key-based lookup, membership, iteration, and the most common construction patterns. Core dictionary patterns What membership and equality actually test Minimal code pattern for iteration Dictionary comprehension and filtering Transform parallel sequences into a dictionary Count or sum dictionary values Delete only keys that also exist elsewhere Ordered output from a dictionary Dictionary methods and iteration quick table", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "dm-mk-1", + "title": "Core dictionary patterns", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns" + ], + "pieces": [ + { + "id": "dm-mk-1-table", + "piece_type": "reference_table", + "title": "Core dictionary patterns", + "order": 1, + "content": { + "text": "", + "headers": [ + "Goal", + "Pattern" + ], + "rows": [ + [ + "create", + "{'a': 1, 'b': 2}" + ], + [ + "lookup by key", + "d['a']" + ], + [ + "safe membership check", + "'a' in d" + ], + [ + "safe lookup with fallback", + "d.get('a', 0)" + ], + [ + "iterate keys and values", + "for key, value in d.items():" + ], + [ + "build from pairs", + "dict(zip(keys, values))" + ], + [ + "build with logic", + "{x: len(x) for x in words}" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns" + ] + } + ] + }, + { + "id": "dm-mk-2", + "title": "What membership and equality actually test", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns", + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ], + "pieces": [ + { + "id": "dm-mk-2-table", + "piece_type": "reference_table", + "title": "What membership and equality actually test", + "order": 1, + "content": { + "text": "", + "headers": [ + "Expression", + "What it means" + ], + "rows": [ + [ + "'x' in d", + "checks keys only" + ], + [ + "3 in d.values()", + "checks values explicitly" + ], + [ + "{1: 10, 2: 20} == {2: 20, 1: 10}", + "True, insertion order does not matter" + ], + [ + "for key in d", + "same as looping over d.keys()" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns", + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ] + } + ] + }, + { + "id": "dm-mk-3", + "title": "Minimal code pattern for iteration", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns", + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ], + "pieces": [ + { + "id": "dm-mk-3-code", + "piece_type": "code_example", + "title": "Minimal code pattern for iteration", + "order": 1, + "content": { + "text": "Most dictionary-loop questions reduce to deciding whether you need keys, values, or both.", + "code": "d = {'a': 3, 'b': 5}\nfor key in d:\n print(key, d[key])\n\nfor key, value in d.items():\n print(key, value)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns", + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "dm-ep-1", + "title": "Dictionary comprehension and filtering", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns", + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ], + "pieces": [ + { + "id": "dm-ep-1-code", + "piece_type": "code_example", + "title": "Dictionary comprehension and filtering", + "order": 1, + "content": { + "text": "If the question asks for a dictionary result, remember that the `key: value` pair comes before `for`.", + "code": "scores = {'Ann': 8, 'Bob': 5, 'Cara': 9}\npassed = {name: score for name, score in scores.items() if score >= 6}", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns", + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ] + }, + { + "id": "dm-ep-2", + "title": "Transform parallel sequences into a dictionary", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns" + ], + "pieces": [ + { + "id": "dm-ep-2-code", + "piece_type": "code_example", + "title": "Transform parallel sequences into a dictionary", + "order": 1, + "content": { + "text": "Use `dict(zip(...))` when the question starts from two separate lists or tuples.", + "code": "keys = ['x', 'y', 'z']\nvalues = [1, 2, 3]\nd = dict(zip(keys, values))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns" + ] + } + ] + }, + { + "id": "dm-ep-3", + "title": "Count or sum dictionary values", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns" + ], + "pieces": [ + { + "id": "dm-ep-3-code", + "piece_type": "code_example", + "title": "Count or sum dictionary values", + "order": 1, + "content": { + "text": "Many exam questions hide the fact that only the values matter.", + "code": "sales = {'a': 3, 'b': 5, 'c': 2}\nprint(sum(sales.values())) # 10", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "dm-ub-1", + "title": "Delete only keys that also exist elsewhere", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ], + "pieces": [ + { + "id": "dm-ub-1-code", + "piece_type": "code_example", + "title": "Delete only keys that also exist elsewhere", + "order": 1, + "content": { + "text": "Useful when the exam mixes membership checks with mutation.", + "code": "x = {'a': 1, 'b': 2, 'c': 3}\nto_remove = {'c': 3, 'd': 3}\nfor key in to_remove:\n if key in x:\n del x[key]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ] + } + ] + }, + { + "id": "dm-ub-2", + "title": "Ordered output from a dictionary", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns" + ], + "pieces": [ + { + "id": "dm-ub-2-code", + "piece_type": "code_example", + "title": "Ordered output from a dictionary", + "order": 1, + "content": { + "text": "Only sort keys when the question cares about printed order.", + "code": "for key in sorted(d.keys()):\n print(key, d[key])", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns" + ] + } + ] + } + ] + }, + { + "key": "quick_tables", + "title": "Quick Tables", + "description": "", + "initial_visible_count": 1, + "snippets": [ + { + "id": "dm-qt-1", + "title": "Dictionary methods and iteration quick table", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Dictionaries and Mappings", + "summary": "", + "source_refs": [ + "manual-dictionary-patterns" + ], + "pieces": [ + { + "id": "dm-qt-1-table", + "piece_type": "reference_table", + "title": "Dictionary methods and iteration quick table", + "order": 1, + "content": { + "text": "This restores the compact dictionary method scan table that helps eliminate distractors quickly.", + "headers": [ + "Pattern", + "Use it for" + ], + "rows": [ + [ + "d[key]", + "direct lookup by key" + ], + [ + "d.get(key, default)", + "safe lookup with fallback" + ], + [ + "key in d", + "membership over keys" + ], + [ + "d.keys() / d.values() / d.items()", + "iterate keys, values, or both" + ], + [ + "dict(zip(keys, values))", + "build from paired iterables" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns" + ] + }, + { + "id": "dm-qt-1-text", + "piece_type": "explanation", + "title": "Dictionary methods and iteration quick table", + "order": 2, + "content": { + "text": "This restores the compact dictionary method scan table that helps eliminate distractors quickly." + }, + "selectable": true, + "source_refs": [ + "manual-dictionary-patterns" + ] + } + ] + } + ] + } + ] + }, + { + "id": "loops", + "title": "Loops", + "summary": "Choosing the right loop, using enumerate/zip/items cleanly, and avoiding the standard exam traps.", + "parent_topic": "Collections and Iteration", + "main_week": 2, + "related_weeks": [ + 2, + 6 + ], + "topic_order": 7, + "search_text": "Loops Choosing the right loop, using enumerate/zip/items cleanly, and avoiding the standard exam traps. Pick the loop shape first break, continue, and loop control Common helper patterns Count matches with sum of booleans Translate a slice into an explicit loop Nested loops for pairwise results Loop variable intentionally unused Iterator basics range(start, stop, step) still excludes stop Loop helper cheat table", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "lp-mk-1", + "title": "Pick the loop shape first", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "manual-iteration-helpers", + "snippet-item-kp-manual-loop-core-d1" + ], + "pieces": [ + { + "id": "lp-mk-1-table", + "piece_type": "reference_table", + "title": "Pick the loop shape first", + "order": 1, + "content": { + "text": "", + "headers": [ + "Need", + "Best pattern" + ], + "rows": [ + [ + "visit every item in an iterable", + "for x in xs:" + ], + [ + "repeat a fixed number of times", + "for _ in range(n):" + ], + [ + "need index and value", + "for i, x in enumerate(xs):" + ], + [ + "walk two iterables together", + "for left, right in zip(a, b):" + ], + [ + "continue while a condition stays true", + "while condition:" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-iteration-helpers", + "snippet-item-kp-manual-loop-core-d1" + ] + } + ] + }, + { + "id": "lp-mk-2", + "title": "break, continue, and loop control", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "snippet-item-manual-break-continue", + "snippet-item-kp-manual-while-truthy" + ], + "pieces": [ + { + "id": "lp-mk-2-table", + "piece_type": "reference_table", + "title": "break, continue, and loop control", + "order": 1, + "content": { + "text": "", + "headers": [ + "Statement", + "Effect" + ], + "rows": [ + [ + "break", + "exit the loop immediately" + ], + [ + "continue", + "skip the rest of this iteration" + ], + [ + "while items:", + "keep looping while the list is non-empty" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-item-manual-break-continue", + "snippet-item-kp-manual-while-truthy" + ] + } + ] + }, + { + "id": "lp-mk-3", + "title": "Common helper patterns", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "manual-iteration-helpers", + "snippet-subtopic-w2-loops-w2-loops-core" + ], + "pieces": [ + { + "id": "lp-mk-3-code", + "piece_type": "code_example", + "title": "Common helper patterns", + "order": 1, + "content": { + "text": "These three patterns cover most loop-structure questions.", + "code": "letters = ['a', 'b', 'c']\nfor index, letter in enumerate(letters, start=1):\n print(index, letter)\n\nfor left, right in zip(['x', 'y'], [10, 20]):\n print(left, right)\n\nfor key, value in {'a': 1, 'b': 2}.items():\n print(key, value)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-iteration-helpers", + "snippet-subtopic-w2-loops-w2-loops-core" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "lp-ep-1", + "title": "Count matches with sum of booleans", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "manual-iteration-helpers" + ], + "pieces": [ + { + "id": "lp-ep-1-code", + "piece_type": "code_example", + "title": "Count matches with sum of booleans", + "order": 1, + "content": { + "text": "In Python, `True` counts as 1 and `False` counts as 0 in numeric contexts.", + "code": "nums = [2, 5, 8, 9]\ncount = sum(x % 2 != 0 for x in nums)\nprint(count) # 2", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-iteration-helpers" + ] + } + ] + }, + { + "id": "lp-ep-2", + "title": "Translate a slice into an explicit loop", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "snippet-item-manual-loop-translate" + ], + "pieces": [ + { + "id": "lp-ep-2-code", + "piece_type": "code_example", + "title": "Translate a slice into an explicit loop", + "order": 1, + "content": { + "text": "Useful when the exam asks you to rewrite slicing logic as a loop.", + "code": "alphabet = ['a', 'b', 'c', 'd', 'e', 'f']\nresult = []\nfor i in range(1, len(alphabet), 2):\n result.append(alphabet[i])", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-item-manual-loop-translate" + ] + } + ] + }, + { + "id": "lp-ep-3", + "title": "Nested loops for pairwise results", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-loops-w2-loops-core" + ], + "pieces": [ + { + "id": "lp-ep-3-code", + "piece_type": "code_example", + "title": "Nested loops for pairwise results", + "order": 1, + "content": { + "text": "If every item must be combined with every other item, expect a nested loop.", + "code": "result = {}\nfor first in range(1, 4):\n for second in range(1, 4):\n result[(first, second)] = first + second", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-loops-w2-loops-core" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "lp-ub-1", + "title": "Loop variable intentionally unused", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "snippet-subtopic-w2-loops-w2-loops-core" + ], + "pieces": [ + { + "id": "lp-ub-1-code", + "piece_type": "code_example", + "title": "Loop variable intentionally unused", + "order": 1, + "content": { + "text": "Use `_` when only the number of repetitions matters.", + "code": "for _ in range(3):\n print('repeat')", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w2-loops-w2-loops-core" + ] + } + ] + }, + { + "id": "lp-ub-2", + "title": "Iterator basics", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "snippet-subtopic-w6-generators-and-iterators-w6-generators-and-iterators-core" + ], + "pieces": [ + { + "id": "lp-ub-2-code", + "piece_type": "code_example", + "title": "Iterator basics", + "order": 1, + "content": { + "text": "Low priority for the shipped UI, but helpful if a question mentions `iter()` or `next()` directly.", + "code": "it = iter([1, 2])\nprint(next(it))\nprint(next(it))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-generators-and-iterators-w6-generators-and-iterators-core" + ] + } + ] + }, + { + "id": "lp-ub-3", + "title": "range(start, stop, step) still excludes stop", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "manual-iteration-helpers" + ], + "pieces": [ + { + "id": "lp-ub-3-table", + "piece_type": "reference_table", + "title": "range(start, stop, step) still excludes stop", + "order": 1, + "content": { + "text": "Off-by-one mistakes in `range(...)` still decide a surprising number of loop questions.", + "headers": [ + "Code", + "Result", + "Why" + ], + "rows": [ + [ + "list(range(6))", + "[0, 1, 2, 3, 4, 5]", + "starts at 0 by default" + ], + [ + "list(range(3, 6))", + "[3, 4, 5]", + "stop value 6 is excluded" + ], + [ + "list(range(3, 9, 2))", + "[3, 5, 7]", + "step controls the jump size" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-iteration-helpers" + ] + }, + { + "id": "lp-ub-3-text", + "piece_type": "explanation", + "title": "range(start, stop, step) still excludes stop", + "order": 2, + "content": { + "text": "Off-by-one mistakes in `range(...)` still decide a surprising number of loop questions." + }, + "selectable": true, + "source_refs": [ + "manual-iteration-helpers" + ] + } + ] + } + ] + }, + { + "key": "quick_tables", + "title": "Quick Tables", + "description": "", + "initial_visible_count": 1, + "snippets": [ + { + "id": "lp-qt-1", + "title": "Loop helper cheat table", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Loops", + "summary": "", + "source_refs": [ + "manual-iteration-helpers", + "snippet-item-manual-break-continue" + ], + "pieces": [ + { + "id": "lp-qt-1-table", + "piece_type": "reference_table", + "title": "Loop helper cheat table", + "order": 1, + "content": { + "text": "These are the loop helpers most worth keeping nearby during the exam.", + "headers": [ + "Need", + "Pattern" + ], + "rows": [ + [ + "index + value", + "for i, x in enumerate(xs):" + ], + [ + "pair two iterables", + "for left, right in zip(a, b):" + ], + [ + "repeat n times", + "for _ in range(n):" + ], + [ + "skip current iteration", + "continue" + ], + [ + "exit loop entirely", + "break" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-iteration-helpers", + "snippet-item-manual-break-continue" + ] + }, + { + "id": "lp-qt-1-text", + "piece_type": "explanation", + "title": "Loop helper cheat table", + "order": 2, + "content": { + "text": "These are the loop helpers most worth keeping nearby during the exam." + }, + "selectable": true, + "source_refs": [ + "manual-iteration-helpers", + "snippet-item-manual-break-continue" + ] + } + ] + } + ] + } + ] + }, + { + "id": "comprehensions", + "title": "Comprehensions", + "summary": "Recognize list/set/dict comprehension syntax quickly and separate filtering from value transformation.", + "parent_topic": "Collections and Iteration", + "main_week": 6, + "related_weeks": [ + 2, + 6 + ], + "topic_order": 8, + "search_text": "Comprehensions Recognize list/set/dict comprehension syntax quickly and separate filtering from value transformation. Comprehension templates Filter vs transform placement rule String output still needs join Dictionary comprehension with items() Set comprehension means uniqueness enumerate inside a comprehension Nested comprehension example The expression must produce a value, not a side effect", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "cp-mk-1", + "title": "Comprehension templates", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "manual-comprehension-syntax" + ], + "pieces": [ + { + "id": "cp-mk-1-table", + "piece_type": "reference_table", + "title": "Comprehension templates", + "order": 1, + "content": { + "text": "", + "headers": [ + "Type", + "Template", + "Example" + ], + "rows": [ + [ + "list", + "[expr for x in xs]", + "[x * 2 for x in xs]" + ], + [ + "list with filter", + "[expr for x in xs if cond]", + "[x for x in xs if x > 0]" + ], + [ + "list with if/else", + "[a if cond else b for x in xs]", + "[x if x > 0 else 0 for x in xs]" + ], + [ + "set", + "{expr for x in xs}", + "{len(name) for name in names}" + ], + [ + "dict", + "{key: value for x in xs}", + "{name: len(name) for name in names}" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-comprehension-syntax" + ] + } + ] + }, + { + "id": "cp-mk-2", + "title": "Filter vs transform placement rule", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "manual-comprehension-syntax", + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ], + "pieces": [ + { + "id": "cp-mk-2-code", + "piece_type": "code_example", + "title": "Filter vs transform placement rule", + "order": 1, + "content": { + "text": "Trailing `if` removes items. Inline `a if cond else b` changes the output value while keeping one output per input.", + "code": "positives = [value for value in nums if value > 0]\nflipped = [letter.lower() if letter.isupper() else letter.upper() for letter in letters]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-comprehension-syntax", + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ] + }, + { + "id": "cp-mk-3", + "title": "String output still needs join", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ], + "pieces": [ + { + "id": "cp-mk-3-code", + "piece_type": "code_example", + "title": "String output still needs join", + "order": 1, + "content": { + "text": "Python has list comprehensions, not native string comprehensions. Build characters first, then `''.join(...)` them.", + "code": "result = ''.join([char * 2 if char.lower() in 'aeiou' else char for char in 'Python'])", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "cp-ep-1", + "title": "Dictionary comprehension with items()", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ], + "pieces": [ + { + "id": "cp-ep-1-code", + "piece_type": "code_example", + "title": "Dictionary comprehension with items()", + "order": 1, + "content": { + "text": "This is the standard exam pattern for filtering or transforming dictionaries.", + "code": "d = {'a': 1, 'b': 2}\nfiltered = {k: v for k, v in d.items() if v > 1}", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ] + }, + { + "id": "cp-ep-2", + "title": "Set comprehension means uniqueness", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ], + "pieces": [ + { + "id": "cp-ep-2-code", + "piece_type": "code_example", + "title": "Set comprehension means uniqueness", + "order": 1, + "content": { + "text": "Use a set comprehension when duplicates should collapse automatically.", + "code": "values = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}\nprint(values)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ] + }, + { + "id": "cp-ep-3", + "title": "enumerate inside a comprehension", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ], + "pieces": [ + { + "id": "cp-ep-3-code", + "piece_type": "code_example", + "title": "enumerate inside a comprehension", + "order": 1, + "content": { + "text": "Keep this pattern in reserve when the expression depends on both index and value.", + "code": "res = [val // (i + 6) for i, val in enumerate([46, 48])]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "cp-ub-1", + "title": "Nested comprehension example", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ], + "pieces": [ + { + "id": "cp-ub-1-code", + "piece_type": "code_example", + "title": "Nested comprehension example", + "order": 1, + "content": { + "text": "Useful if the exam includes nested structures, but too advanced to surface as core shipped material.", + "code": "result = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ] + }, + { + "id": "cp-ub-2", + "title": "The expression must produce a value, not a side effect", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Collections and Iteration", + "main_topic": "Comprehensions", + "summary": "", + "source_refs": [ + "manual-comprehension-syntax" + ], + "pieces": [ + { + "id": "cp-ub-2-table", + "piece_type": "reference_table", + "title": "The expression must produce a value, not a side effect", + "order": 1, + "content": { + "text": "Use comprehensions to build values. If the real goal is mutation or printing, a normal loop is clearer and usually correct.", + "headers": [ + "Wrong instinct", + "Why it fails", + "Better pattern" + ], + "rows": [ + [ + "[result.append(x) for x in xs]", + "append returns `None`, so the comprehension collects `None` values", + "[x for x in xs] or build the list in a normal loop" + ], + [ + "[print(x) for x in xs]", + "prints as a side effect instead of building useful values", + "use a normal loop for printing" + ], + [ + "{d.update({k: v}) for k, v in pairs}", + "update mutates and returns `None`", + "{k: v for k, v in pairs}" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-comprehension-syntax" + ] + }, + { + "id": "cp-ub-2-text", + "piece_type": "explanation", + "title": "The expression must produce a value, not a side effect", + "order": 2, + "content": { + "text": "Use comprehensions to build values. If the real goal is mutation or printing, a normal loop is clearer and usually correct." + }, + "selectable": true, + "source_refs": [ + "manual-comprehension-syntax" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "functions-and-program-flow", + "title": "Functions and Program Flow", + "summary": "Manual curation draft for the shipped UI. This parent topic keeps only compact, exam-useful material for function syntax, imports, flexible arguments, scope/return behavior, and lambda-style patterns.", + "source_refs": { + "draft_file": "functions_and_program_flow.json" + }, + "main_topics": [ + { + "id": "functions-and-imports", + "title": "Functions and Imports", + "summary": "Defining a function, calling it correctly, and knowing which names an import statement actually creates.", + "parent_topic": "Functions and Program Flow", + "main_week": 3, + "related_weeks": [ + 1, + 3 + ], + "topic_order": 9, + "search_text": "Functions and Imports Defining a function, calling it correctly, and knowing which names an import statement actually creates. Define with `def`, call with `()`, and return the value you want the caller to use Import name-binding reference Alias trap: the alias replaces the old module name in your code In multi-branch function questions, check both the logic and the exact return shape Useful built-ins that often appear inside small helper functions", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "fi-call-return-basics", + "title": "Define with `def`, call with `()`, and return the value you want the caller to use", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Functions and Imports", + "summary": "", + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-2", + "topic_cards.json#w3-defining-and-calling-functions:kp-1", + "topic_cards.json#w3-defining-and-calling-functions:kp-3" + ], + "pieces": [ + { + "id": "fi-call-return-basics-code", + "piece_type": "code_example", + "title": "Define with `def`, call with `()`, and return the value you want the caller to use", + "order": 1, + "content": { + "text": "Use `def name(params):` to define a function. Call it with `name(...)`. `print(...)` only displays a value; `return` sends it back to the caller.", + "code": "def add(a, b):\n return a + b\n\nresult = add(2, 3)\nprint(result) # 5", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-2", + "topic_cards.json#w3-defining-and-calling-functions:kp-1", + "topic_cards.json#w3-defining-and-calling-functions:kp-3" + ] + } + ] + }, + { + "id": "fi-import-binding-reference", + "title": "Import name-binding reference", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Functions and Imports", + "summary": "", + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-1", + "topic_cards.json#w1-functions-and-imports:ai-example-1", + "topic_cards.json#w1-functions-and-imports:ai-example-2", + "topic_cards.json#w1-functions-and-imports:ai-example-5" + ], + "pieces": [ + { + "id": "fi-import-binding-reference-table", + "piece_type": "reference_table", + "title": "Import name-binding reference", + "order": 1, + "content": { + "text": "The important exam question is not what module was imported, but which name is actually available afterwards.", + "headers": [ + "Statement", + "Use this name later", + "Not this" + ], + "rows": [ + [ + "import math", + "math.pi", + "pi" + ], + [ + "import math as m", + "m.pi", + "math.pi" + ], + [ + "from math import pi", + "pi", + "math.pi" + ], + [ + "from math import pi as constant", + "constant", + "pi" + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-1", + "topic_cards.json#w1-functions-and-imports:ai-example-1", + "topic_cards.json#w1-functions-and-imports:ai-example-2", + "topic_cards.json#w1-functions-and-imports:ai-example-5" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "fi-alias-trap", + "title": "Alias trap: the alias replaces the old module name in your code", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Functions and Imports", + "summary": "", + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:exam-intro_python_sample_final_24_25-24-w2-conditions" + ], + "pieces": [ + { + "id": "fi-alias-trap-table", + "piece_type": "reference_table", + "title": "Alias trap: the alias replaces the old module name in your code", + "order": 1, + "content": { + "text": "", + "headers": [ + "Code", + "Works?", + "Why" + ], + "rows": [ + [ + "import math as constants\\nconstants.pi", + "Yes", + "You must use the alias you created." + ], + [ + "import math as constants\\nmath.pi", + "No", + "The bare name `math` was never bound." + ], + [ + "from math import pi as constant\\nconstant * r ** 2", + "Yes", + "The imported name is `constant`." + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:exam-intro_python_sample_final_24_25-24-w2-conditions" + ] + } + ] + }, + { + "id": "fi-branch-return-shape", + "title": "In multi-branch function questions, check both the logic and the exact return shape", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Functions and Imports", + "summary": "", + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:exam-midterm_2023-12-w1-functions-and-imports" + ], + "pieces": [ + { + "id": "fi-branch-return-shape-text", + "piece_type": "explanation", + "title": "In multi-branch function questions, check both the logic and the exact return shape", + "order": 1, + "content": { + "text": "A function can fail an exam question even when the math is almost right. Check three things: every branch assigns the needed values, the function returns the requested object shape, and helper code is used as a value rather than left as a function object." + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:exam-midterm_2023-12-w1-functions-and-imports" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "fi-builtins-mini-reference", + "title": "Useful built-ins that often appear inside small helper functions", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Functions and Imports", + "summary": "", + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-1-d2" + ], + "pieces": [ + { + "id": "fi-builtins-mini-reference-table", + "piece_type": "reference_table", + "title": "Useful built-ins that often appear inside small helper functions", + "order": 1, + "content": { + "text": "", + "headers": [ + "Call", + "Purpose", + "Typical result" + ], + "rows": [ + [ + "int('123')", + "string to integer", + "123" + ], + [ + "float('123')", + "string to float", + "123.0" + ], + [ + "str(123.0)", + "number to string", + "'123.0'" + ], + [ + "round(x, 2)", + "round for display/checking", + "2 decimals" + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-1-d2" + ] + } + ] + } + ] + } + ] + }, + { + "id": "flexible-arguments-and-kwargs", + "title": "Flexible Arguments and kwargs", + "summary": "Reading function headers with defaults, `*args`, and `**kwargs`, and tracing what a call actually passes in.", + "parent_topic": "Functions and Program Flow", + "main_week": 3, + "related_weeks": [ + 3 + ], + "topic_order": 10, + "search_text": "Flexible Arguments and kwargs Reading function headers with defaults, `*args`, and `**kwargs`, and tracing what a call actually passes in. Read the function header from left to right Defaults are evaluated once; never use a mutable object as the default Keyword arguments can appear in any order as long as the names match Mixed header pattern: required values first, then extras, then named options Flexible header plus tuple return", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "fa-signature-reference", + "title": "Read the function header from left to right", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Flexible Arguments and kwargs", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-arguments:kp-1", + "topic_cards.json#w3-arguments:kp-2", + "topic_cards.json#w3-arguments:kp-manual-args-kwargs-return" + ], + "pieces": [ + { + "id": "fa-signature-reference-table", + "piece_type": "reference_table", + "title": "Read the function header from left to right", + "order": 1, + "content": { + "text": "", + "headers": [ + "Header piece", + "Meaning" + ], + "rows": [ + [ + "x", + "required positional parameter" + ], + [ + "y=0", + "optional parameter with a default" + ], + [ + "*args", + "extra positional arguments as a tuple" + ], + [ + "**kwargs", + "extra keyword arguments as a dict" + ], + [ + "return a, b", + "one tuple comes back" + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-arguments:kp-1", + "topic_cards.json#w3-arguments:kp-2", + "topic_cards.json#w3-arguments:kp-manual-args-kwargs-return" + ] + } + ] + }, + { + "id": "fa-defaults-and-none-fix", + "title": "Defaults are evaluated once; never use a mutable object as the default", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Flexible Arguments and kwargs", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-arguments:kp-3", + "topic_cards.json#w3-arguments:ai-example-6" + ], + "pieces": [ + { + "id": "fa-defaults-and-none-fix-code", + "piece_type": "code_example", + "title": "Defaults are evaluated once; never use a mutable object as the default", + "order": 1, + "content": { + "text": "A list or dict default persists across calls. Use `None` and create a fresh container inside the function.", + "code": "def collect(item, items=None):\n if items is None:\n items = []\n items.append(item)\n return items", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-arguments:kp-3", + "topic_cards.json#w3-arguments:ai-example-6" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "fa-keyword-order-pattern", + "title": "Keyword arguments can appear in any order as long as the names match", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Flexible Arguments and kwargs", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-arguments:kp-2-d1", + "topic_cards.json#w3-arguments:ai-example-3" + ], + "pieces": [ + { + "id": "fa-keyword-order-pattern-code", + "piece_type": "code_example", + "title": "Keyword arguments can appear in any order as long as the names match", + "order": 1, + "content": { + "text": "The call order does not matter here because the argument names decide where each value goes.", + "code": "def calc(first, second, third):\n return first + 2 * second + 3 * third\n\nprint(calc(third=4, second=2, first=3)) # 19", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-arguments:kp-2-d1", + "topic_cards.json#w3-arguments:ai-example-3" + ] + } + ] + }, + { + "id": "fa-mixed-flexible-header-pattern", + "title": "Mixed header pattern: required values first, then extras, then named options", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Flexible Arguments and kwargs", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-arguments:exam-midterm_2024-14-w3-arguments" + ], + "pieces": [ + { + "id": "fa-mixed-flexible-header-pattern-code", + "piece_type": "code_example", + "title": "Mixed header pattern: required values first, then extras, then named options", + "order": 1, + "content": { + "text": "Common exam move: `*args` collects the numbers, while a named option like `factor=` stays readable in the call.", + "code": "def multiply(*args, factor=2):\n total = 1\n for num in args:\n total *= num\n return total * factor", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-arguments:exam-midterm_2024-14-w3-arguments" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "fa-tuple-return-unpack", + "title": "Flexible header plus tuple return", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Flexible Arguments and kwargs", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-arguments:manual-args-kwargs-return" + ], + "pieces": [ + { + "id": "fa-tuple-return-unpack-code", + "piece_type": "code_example", + "title": "Flexible header plus tuple return", + "order": 1, + "content": { + "text": "This is compact but high-value because it combines the most common header features in one traceable example.", + "code": "def collect(first, *args, scale=1, **kwargs):\n return first * scale, args, kwargs\n\nresult, extras, options = collect(2, 3, 4, scale=10, unit='cm')\nprint(result) # 20\nprint(extras) # (3, 4)\nprint(options) # {'unit': 'cm'}", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-arguments:manual-args-kwargs-return" + ] + } + ] + } + ] + } + ] + }, + { + "id": "scope-and-return-behavior", + "title": "Scope and Return Behavior", + "summary": "What names exist where, how values escape a function, and why `None` appears so often in function questions.", + "parent_topic": "Functions and Program Flow", + "main_week": 3, + "related_weeks": [ + 3 + ], + "topic_order": 11, + "search_text": "Scope and Return Behavior What names exist where, how values escape a function, and why `None` appears so often in function questions. Scope rules to check before tracing any function `return` sends a value back; `print` only shows it Common `None` traps Local-name error: computing a value inside the function does not make it global Self-reference after assignment makes the name local and uninitialized Small syntax traps worth keeping in backup", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "sr-scope-rules", + "title": "Scope rules to check before tracing any function", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Scope and Return Behavior", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-scope:kp-manual-scope-local", + "topic_cards.json#w3-scope:kp-manual-scope-unbound", + "topic_cards.json#w3-scope:kp-manual-scope-global", + "topic_cards.json#w3-scope:kp-manual-scope-return-outside" + ], + "pieces": [ + { + "id": "sr-scope-rules-table", + "piece_type": "reference_table", + "title": "Scope rules to check before tracing any function", + "order": 1, + "content": { + "text": "", + "headers": [ + "Rule", + "Consequence" + ], + "rows": [ + [ + "Parameter names and assigned names inside a function are local by default.", + "They cannot be used outside that function." + ], + [ + "If a function assigns to a name anywhere, Python treats that name as local throughout that function.", + "You can get `UnboundLocalError` even before the assignment line." + ], + [ + "`global x` rebinds the global name `x`.", + "Use it only when you really want to change the global." + ], + [ + "`nonlocal x` rebinds the nearest enclosing local name `x`.", + "Use it in nested functions when you want the inner function to update the outer function's variable." + ], + [ + "If the caller needs a value later, return it and assign the result.", + "Do not expect local names to survive the call." + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-scope:kp-manual-scope-local", + "topic_cards.json#w3-scope:kp-manual-scope-unbound", + "topic_cards.json#w3-scope:kp-manual-scope-global", + "topic_cards.json#w3-scope:kp-manual-scope-return-outside" + ] + } + ] + }, + { + "id": "sr-return-vs-print", + "title": "`return` sends a value back; `print` only shows it", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Scope and Return Behavior", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-1", + "topic_cards.json#w3-return-behavior:ai-example-5", + "topic_cards.json#w3-return-behavior:ai-example-6" + ], + "pieces": [ + { + "id": "sr-return-vs-print-text", + "piece_type": "explanation", + "title": "`return` sends a value back; `print` only shows it", + "order": 1, + "content": { + "text": "A function that prints a value but does not return it still returns `None`. In exam traces, always ask: what comes back to the caller?" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-1", + "topic_cards.json#w3-return-behavior:ai-example-5", + "topic_cards.json#w3-return-behavior:ai-example-6" + ] + } + ] + }, + { + "id": "sr-none-traps", + "title": "Common `None` traps", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Scope and Return Behavior", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-2", + "topic_cards.json#w3-return-behavior:kp-manual-mutating-methods-none", + "topic_cards.json#w3-defining-and-calling-functions:kp-2" + ], + "pieces": [ + { + "id": "sr-none-traps-table", + "piece_type": "reference_table", + "title": "Common `None` traps", + "order": 1, + "content": { + "text": "", + "headers": [ + "Code shape", + "What comes back" + ], + "rows": [ + [ + "function reaches end with no `return`", + "None" + ], + [ + "branch that never hits a `return`", + "None" + ], + [ + "l1.sort() / l1.append(x)", + "None" + ], + [ + "s.upper()", + "new string" + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-2", + "topic_cards.json#w3-return-behavior:kp-manual-mutating-methods-none", + "topic_cards.json#w3-defining-and-calling-functions:kp-2" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "sr-local-name-outside-function", + "title": "Local-name error: computing a value inside the function does not make it global", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Scope and Return Behavior", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-scope:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "topic_cards.json#w3-scope:exam-Resit 22/23-2-w3-scope" + ], + "pieces": [ + { + "id": "sr-local-name-outside-function-code", + "piece_type": "code_example", + "title": "Local-name error: computing a value inside the function does not make it global", + "order": 1, + "content": { + "text": "`result` is local to `power`, so `print(result)` outside the function fails.", + "code": "def power(num, factor):\n result = num ** factor\n return result\n\nprint(result)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-scope:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "topic_cards.json#w3-scope:exam-Resit 22/23-2-w3-scope" + ] + } + ] + }, + { + "id": "sr-unboundlocal-pattern", + "title": "Self-reference after assignment makes the name local and uninitialized", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Scope and Return Behavior", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-scope:manual-scope-unbound" + ], + "pieces": [ + { + "id": "sr-unboundlocal-pattern-code", + "piece_type": "code_example", + "title": "Self-reference after assignment makes the name local and uninitialized", + "order": 1, + "content": { + "text": "Because `b` is assigned inside `main`, Python treats it as local from the start of the function. The right-hand `b` has no value yet.", + "code": "b = 1\n\ndef main(a):\n b = b\n return a\n\nprint(main(1))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-scope:manual-scope-unbound" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "sr-one-element-tuple-pass", + "title": "Small syntax traps worth keeping in backup", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Scope and Return Behavior", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-3", + "topic_cards.json#w3-return-behavior:kp-4" + ], + "pieces": [ + { + "id": "sr-one-element-tuple-pass-table", + "piece_type": "reference_table", + "title": "Small syntax traps worth keeping in backup", + "order": 1, + "content": { + "text": "", + "headers": [ + "Pattern", + "Meaning" + ], + "rows": [ + [ + "(1)", + "just the integer 1" + ], + [ + "(1,)", + "one-element tuple" + ], + [ + "pass", + "placeholder statement; does nothing" + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-3", + "topic_cards.json#w3-return-behavior:kp-4" + ] + } + ] + } + ] + } + ] + }, + { + "id": "lambda-and-higher-order-patterns", + "title": "Lambda and Higher-Order Patterns", + "summary": "Small inline functions, `map(...)`, `sorted(..., key=...)`, and the few recurring higher-order patterns that show up in exams.", + "parent_topic": "Functions and Program Flow", + "main_week": 3, + "related_weeks": [ + 3 + ], + "topic_order": 12, + "search_text": "Lambda and Higher-Order Patterns Small inline functions, `map(...)`, `sorted(..., key=...)`, and the few recurring higher-order patterns that show up in exams. Compact lambda / map / sorted reference `map(...)` is lazy; wrap it in `list(...)` when the question expects visible values Sort by a property, not by the raw value Apply several functions to the same input Check whether the function expects one number or the whole list Nested function / factory pattern", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "lh-lambda-map-sorted-reference", + "title": "Compact lambda / map / sorted reference", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Lambda and Higher-Order Patterns", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:kp-2", + "topic_cards.json#w3-higher-order-patterns:kp-3", + "topic_cards.json#w3-higher-order-patterns:ai-example-8" + ], + "pieces": [ + { + "id": "lh-lambda-map-sorted-reference-table", + "piece_type": "reference_table", + "title": "Compact lambda / map / sorted reference", + "order": 1, + "content": { + "text": "", + "headers": [ + "Pattern", + "Use" + ], + "rows": [ + [ + "lambda x: x * 2", + "small inline function for one value" + ], + [ + "list(map(f, seq))", + "apply `f` to every element and materialize the result" + ], + [ + "sorted(seq, key=f)", + "sort by a computed comparison key" + ], + [ + "sorted(seq, key=f, reverse=True)", + "same key, descending order" + ] + ] + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:kp-2", + "topic_cards.json#w3-higher-order-patterns:kp-3", + "topic_cards.json#w3-higher-order-patterns:ai-example-8" + ] + } + ] + }, + { + "id": "lh-map-is-lazy", + "title": "`map(...)` is lazy; wrap it in `list(...)` when the question expects visible values", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Lambda and Higher-Order Patterns", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:ai-example-3", + "topic_cards.json#w3-higher-order-patterns:kp-3" + ], + "pieces": [ + { + "id": "lh-map-is-lazy-code", + "piece_type": "code_example", + "title": "`map(...)` is lazy; wrap it in `list(...)` when the question expects visible values", + "order": 1, + "content": { + "text": "A common wrong option prints the raw `map` object instead of materializing the mapped values.", + "code": "nums = [1, 2, 3]\nprint(list(map(lambda x: x * 2, nums))) # [2, 4, 6]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:ai-example-3", + "topic_cards.json#w3-higher-order-patterns:kp-3" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "lh-sort-key-pattern", + "title": "Sort by a property, not by the raw value", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Lambda and Higher-Order Patterns", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2023-11-w3-higher-order-patterns" + ], + "pieces": [ + { + "id": "lh-sort-key-pattern-code", + "piece_type": "code_example", + "title": "Sort by a property, not by the raw value", + "order": 1, + "content": { + "text": "This exact exam pattern checks whether you know that `key=` computes the comparison value and `reverse=True` flips the final order.", + "code": "def sort_list(x):\n return sorted(x, key=lambda num: abs(num), reverse=True)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2023-11-w3-higher-order-patterns" + ] + } + ] + }, + { + "id": "lh-function-list-pattern", + "title": "Apply several functions to the same input", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Lambda and Higher-Order Patterns", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2023-13-w3-higher-order-patterns" + ], + "pieces": [ + { + "id": "lh-function-list-pattern-code", + "piece_type": "code_example", + "title": "Apply several functions to the same input", + "order": 1, + "content": { + "text": "Read `lambda f: f(i)` as: take one function from `funcs`, call it on the current number `i`, then collect the outputs.", + "code": "funcs = [square, cube]\nfor i in my_list:\n results = map(lambda f: f(i), funcs)\n print(list(results))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2023-13-w3-higher-order-patterns" + ] + } + ] + }, + { + "id": "lh-whole-list-vs-one-element", + "title": "Check whether the function expects one number or the whole list", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Lambda and Higher-Order Patterns", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-trial_midterm-17-w3-higher-order-patterns", + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2024-19-w3-higher-order-patterns" + ], + "pieces": [ + { + "id": "lh-whole-list-vs-one-element-text", + "piece_type": "explanation", + "title": "Check whether the function expects one number or the whole list", + "order": 1, + "content": { + "text": "Many distractors fail because they pass the entire list into a function that was written for a single element. `map(f, [1,2,3])` calls `f(1)`, then `f(2)`, then `f(3)`; `f([1,2,3])` is a completely different call." + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-trial_midterm-17-w3-higher-order-patterns", + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2024-19-w3-higher-order-patterns" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "lh-function-factory", + "title": "Nested function / factory pattern", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Functions and Program Flow", + "main_topic": "Lambda and Higher-Order Patterns", + "summary": "", + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:kp-1", + "topic_cards.json#w3-higher-order-patterns:ai-example-1" + ], + "pieces": [ + { + "id": "lh-function-factory-code", + "piece_type": "code_example", + "title": "Nested function / factory pattern", + "order": 1, + "content": { + "text": "Lower-frequency than `lambda` and `map`, but still worth keeping as backup because it tests the idea that functions are objects and can be returned.", + "code": "def function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\n\nadd4 = function_factory(4)\nprint(add4(3)) # 7", + "output": "" + }, + "selectable": true, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:kp-1", + "topic_cards.json#w3-higher-order-patterns:ai-example-1" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "strings-and-output", + "title": "Strings and Output", + "summary": "String mechanics, common methods, and compact output-formatting patterns.", + "source_refs": { + "draft_file": "strings_and_output.json" + }, + "main_topics": [ + { + "id": "string-fundamentals", + "title": "String Fundamentals", + "summary": "", + "parent_topic": "Strings and Output", + "main_week": 4, + "related_weeks": [ + 1, + 4 + ], + "topic_order": 13, + "search_text": "String Fundamentals Strings are immutable Escape characters and literal quotes Length and indexing basics Rebuild strings instead of assigning into them Filter characters in a loop Repeat text with * Uppercase helper loop Escape-sequence quick table A compact backup table for the escape and quote patterns that still show up in tiny output questions.", + "source_refs": { + "draft_file": "strings_and_output.json", + "source_ids": [] + }, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "string-fundamentals-must_know-strings-are-immutable", + "title": "Strings are immutable", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "", + "source_refs": [ + "kp-1", + "ks-b734a22f46", + "manual-string-immutability" + ], + "pieces": [ + { + "id": "string-fundamentals-must_know-strings-are-immutable-code", + "piece_type": "code_example", + "title": "Strings are immutable", + "order": 1, + "content": { + "text": "String methods return new strings. If you want the change to persist, assign the result back to a variable.", + "code": "s = 'abcd'\ns = s.upper()", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-1", + "ks-b734a22f46", + "manual-string-immutability" + ] + } + ] + }, + { + "id": "string-fundamentals-must_know-escape-characters-and-literal-quotes", + "title": "Escape characters and literal quotes", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "", + "source_refs": [ + "kp-2", + "ks-309158a68c", + "manual-string-literals-example" + ], + "pieces": [ + { + "id": "string-fundamentals-must_know-escape-characters-and-literal-quotes-code", + "piece_type": "code_example", + "title": "Escape characters and literal quotes", + "order": 1, + "content": { + "text": "Use the other quote style or escape the inner quote. Keep three patterns in mind: backslash-n makes a newline, backslash-t makes a tab, and escaped quotes let the string stay open.", + "code": "print(\"it\\'s\")\nprint('He said \"hi\"')", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-2", + "ks-309158a68c", + "manual-string-literals-example" + ] + } + ] + }, + { + "id": "string-fundamentals-must_know-length-and-indexing-basics", + "title": "Length and indexing basics", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "", + "source_refs": [ + "ai-example-8", + "cs-bb7b598ca1" + ], + "pieces": [ + { + "id": "string-fundamentals-must_know-length-and-indexing-basics-code", + "piece_type": "code_example", + "title": "Length and indexing basics", + "order": 1, + "content": { + "text": "len(s) counts every character in the string, and indexing starts at 0.", + "code": "a = 'adbc'\nprint(len(a))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ai-example-8", + "cs-bb7b598ca1" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "string-fundamentals-exam_patterns-rebuild-strings-instead-of-assigning-into-them", + "title": "Rebuild strings instead of assigning into them", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "", + "source_refs": [ + "kp-3", + "manual-string-immutability" + ], + "pieces": [ + { + "id": "string-fundamentals-exam_patterns-rebuild-strings-instead-of-assigning-into-them-code", + "piece_type": "code_example", + "title": "Rebuild strings instead of assigning into them", + "order": 1, + "content": { + "text": "If an exam asks to change one character, rebuild the string with slicing instead of assigning by index.", + "code": "s = 'A' + s[1:]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-3", + "manual-string-immutability" + ] + } + ] + }, + { + "id": "string-fundamentals-exam_patterns-filter-characters-in-a-loop", + "title": "Filter characters in a loop", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "", + "source_refs": [ + "ai-example-4", + "cs-14245b8c1f" + ], + "pieces": [ + { + "id": "string-fundamentals-exam_patterns-filter-characters-in-a-loop-code", + "piece_type": "code_example", + "title": "Filter characters in a loop", + "order": 1, + "content": { + "text": "Use a running result string when the question asks you to keep only the characters that pass a test.", + "code": "text = 'AbCde'\nresult = ''\nfor ch in text:\n if ch.islower():\n result += ch\nprint(result) # 'bde'", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ai-example-4", + "cs-14245b8c1f" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "string-fundamentals-useful_backup-repeat-text-with", + "title": "Repeat text with *", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "", + "source_refs": [ + "manual-string-repetition" + ], + "pieces": [ + { + "id": "string-fundamentals-useful_backup-repeat-text-with-code", + "piece_type": "code_example", + "title": "Repeat text with *", + "order": 1, + "content": { + "text": "The * operator repeats a string, which sometimes appears in short output questions.", + "code": "print(3 * 'ha')", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-string-repetition" + ] + } + ] + }, + { + "id": "string-fundamentals-useful_backup-uppercase-helper-loop", + "title": "Uppercase helper loop", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "", + "source_refs": [ + "ai-example-4", + "cs-14245b8c1f" + ], + "pieces": [ + { + "id": "string-fundamentals-useful_backup-uppercase-helper-loop-code", + "piece_type": "code_example", + "title": "Uppercase helper loop", + "order": 1, + "content": { + "text": "A tiny helper can make a filtering loop readable when the test itself is part of what the exam is asking about.", + "code": "def my_isupper(s1):\n return s1 == s1.upper() and s1 != s1.lower()\n\nresult = ''\nfor ch in 'AbCdeF':\n if my_isupper(ch):\n result += ch\nprint(result) # 'ACF'", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ai-example-4", + "cs-14245b8c1f" + ] + } + ] + }, + { + "id": "string-fundamentals-useful_backup-escape-sequence-quick-table", + "title": "Escape-sequence quick table", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Fundamentals", + "summary": "A compact backup table for the escape and quote patterns that still show up in tiny output questions.", + "source_refs": [ + "manual-string-literals-example" + ], + "pieces": [ + { + "id": "string-fundamentals-escape-table", + "piece_type": "reference_table", + "title": "Escapes and quote-safe patterns", + "order": 1, + "content": { + "text": "Keep this low on the page, but it is worth having when a syntax fragment has to be read exactly.", + "headers": [ + "Pattern", + "Meaning", + "Example" + ], + "rows": [ + [ + "backslash-n", + "newline", + "\"Line 1\\nLine 2\"" + ], + [ + "backslash-t", + "tab", + "\"A\\tB\"" + ], + [ + "escaped quote", + "literal quote", + "\"it\\'s\" or 'He said \"hi\"'" + ], + [ + "raw string r\"...\"", + "keep backslashes literal", + "r\"c:\\\\temp\\\\file.txt\"" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-string-literals-example", + "manual-string-immutability" + ] + } + ] + } + ] + } + ] + }, + { + "id": "string-operations-and-methods", + "title": "String Operations and Methods", + "summary": "", + "parent_topic": "Strings and Output", + "main_week": 4, + "related_weeks": [ + 4 + ], + "topic_order": 14, + "search_text": "String Operations and Methods find() versus index() split() and join() round-trip replace() returns a new string Step slicing and reverse order Boolean string predicates Trim whitespace and edges String module constants Search with start/stop String-method quick table A compact scan table for the string methods that show up most often in exam options.", + "source_refs": { + "draft_file": "strings_and_output.json", + "source_ids": [] + }, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "string-operations-and-methods-must_know-find-versus-index", + "title": "find() versus index()", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "kp-1", + "kp-7", + "ai-example-1", + "manual-find-vs-index" + ], + "pieces": [ + { + "id": "string-operations-and-methods-must_know-find-versus-index-code", + "piece_type": "code_example", + "title": "find() versus index()", + "order": 1, + "content": { + "text": ".find() returns -1 when the substring is missing; .index() raises ValueError.", + "code": "s = 'abc'\nprint(s.find('z'))\n# print(s.index('z')) # ValueError", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-1", + "kp-7", + "ai-example-1", + "manual-find-vs-index" + ] + } + ] + }, + { + "id": "string-operations-and-methods-must_know-split-and-join-round-trip", + "title": "split() and join() round-trip", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "kp-3", + "ai-example-3", + "manual-string-output-construction" + ], + "pieces": [ + { + "id": "string-operations-and-methods-must_know-split-and-join-round-trip-code", + "piece_type": "code_example", + "title": "split() and join() round-trip", + "order": 1, + "content": { + "text": ".split() turns text into a list, and .join() turns a list back into text with a separator.", + "code": "words = 'a b c'.split()\nprint('-'.join(words))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-3", + "ai-example-3", + "manual-string-output-construction" + ] + } + ] + }, + { + "id": "string-operations-and-methods-must_know-replace-returns-a-new-string", + "title": "replace() returns a new string", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "kp-4", + "ai-example-4", + "kp-manual-string-method-results-d1" + ], + "pieces": [ + { + "id": "string-operations-and-methods-must_know-replace-returns-a-new-string-code", + "piece_type": "code_example", + "title": "replace() returns a new string", + "order": 1, + "content": { + "text": ".replace(old, new, count) creates a new string and can limit how many replacements happen.", + "code": "s = 'aaaa'\nprint(s.replace('a', 'b', 2))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-4", + "ai-example-4", + "kp-manual-string-method-results-d1" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "string-operations-and-methods-exam_patterns-step-slicing-and-reverse-order", + "title": "Step slicing and reverse order", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "kp-2", + "ai-example-2", + "manual-string-indexing-reference" + ], + "pieces": [ + { + "id": "string-operations-and-methods-exam_patterns-step-slicing-and-reverse-order-code", + "piece_type": "code_example", + "title": "Step slicing and reverse order", + "order": 1, + "content": { + "text": "Use s[::2] for every second character, s[::-1] to reverse, and negative indices to count from the end.", + "code": "s = '01234567'\nprint(s[::2])\nprint(s[::-1])", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-2", + "ai-example-2", + "manual-string-indexing-reference" + ] + } + ] + }, + { + "id": "string-operations-and-methods-exam_patterns-boolean-string-predicates", + "title": "Boolean string predicates", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "kp-9", + "manual-string-islower-method" + ], + "pieces": [ + { + "id": "string-operations-and-methods-exam_patterns-boolean-string-predicates-code", + "piece_type": "code_example", + "title": "Boolean string predicates", + "order": 1, + "content": { + "text": ".islower(), .isupper(), and .isdigit() only return True when the string contains matching cased or digit characters.", + "code": "print('amsterdam'.islower())\nprint('123'.islower())", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-9", + "manual-string-islower-method" + ] + } + ] + }, + { + "id": "string-operations-and-methods-exam_patterns-trim-whitespace-and-edges", + "title": "Trim whitespace and edges", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "kp-6", + "ai-example-6", + "manual-string-method-results-d1" + ], + "pieces": [ + { + "id": "string-operations-and-methods-exam_patterns-trim-whitespace-and-edges-code", + "piece_type": "code_example", + "title": "Trim whitespace and edges", + "order": 1, + "content": { + "text": ".strip() removes leading and trailing whitespace; lstrip() and rstrip() remove just one side.", + "code": "s = ' abc '\nprint(s.strip())", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-6", + "ai-example-6", + "manual-string-method-results-d1" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "string-operations-and-methods-useful_backup-string-module-constants", + "title": "String module constants", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "kp-5", + "ai-example-5" + ], + "pieces": [ + { + "id": "string-operations-and-methods-useful_backup-string-module-constants-code", + "piece_type": "code_example", + "title": "String module constants", + "order": 1, + "content": { + "text": "The string module provides ready-made constants such as ascii_lowercase and digits.", + "code": "import string\nprint(string.digits)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-5", + "ai-example-5" + ] + } + ] + }, + { + "id": "string-operations-and-methods-useful_backup-search-with-start-stop", + "title": "Search with start/stop", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "", + "source_refs": [ + "ai-example-7", + "ai-example-8" + ], + "pieces": [ + { + "id": "string-operations-and-methods-useful_backup-search-with-start-stop-code", + "piece_type": "code_example", + "title": "Search with start/stop", + "order": 1, + "content": { + "text": "find() and index() accept optional start and stop positions when a question needs a bounded search.", + "code": "s = 'abcdefgh'\nprint(s.find('e', 5))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ai-example-7", + "ai-example-8" + ] + } + ] + } + ] + }, + { + "key": "quick_tables", + "title": "Quick Tables", + "description": "", + "initial_visible_count": 1, + "snippets": [ + { + "id": "string-operations-and-methods-quick_tables-string-method-quick-table", + "title": "String-method quick table", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "String Operations and Methods", + "summary": "A compact scan table for the string methods that show up most often in exam options.", + "source_refs": [ + "manual-find-vs-index", + "manual-string-method-results-d1" + ], + "pieces": [ + { + "id": "string-methods-quick-table", + "piece_type": "reference_table", + "title": "Common string methods at a glance", + "order": 1, + "content": { + "text": "These are the highest-payoff methods to recognize instantly.", + "headers": [ + "Method", + "What it returns", + "Reminder" + ], + "rows": [ + [ + "s.find(sub)", + "index or -1", + "safe when missing" + ], + [ + "s.index(sub)", + "index or error", + "raises if missing" + ], + [ + "s.replace(a, b)", + "new string", + "string stays immutable" + ], + [ + "s.split(sep)", + "list of parts", + "text -> list" + ], + [ + "sep.join(parts)", + "new string", + "list -> text" + ], + [ + "s.strip()", + "trimmed string", + "edges only" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-find-vs-index", + "manual-string-method-results-d1" + ] + } + ] + } + ] + } + ] + }, + { + "id": "output-formatting", + "title": "Output Formatting", + "summary": "", + "parent_topic": "Strings and Output", + "main_week": 4, + "related_weeks": [ + 3, + 4 + ], + "topic_order": 15, + "search_text": "Output Formatting f-strings for direct interpolation .format() still appears in exams join() plus a custom tail Zero padding and decimal precision Debug output with f'{var=}' Repeated output with * Legacy format width Build the middle, then patch the tail Formatting mini table A small reference for the format specs and output-building patterns that are easiest to forget under pressure.", + "source_refs": { + "draft_file": "strings_and_output.json", + "source_ids": [] + }, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "output-formatting-must_know-f-strings-for-direct-interpolation", + "title": "f-strings for direct interpolation", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "kp-1", + "ks-72dda5450c" + ], + "pieces": [ + { + "id": "output-formatting-must_know-f-strings-for-direct-interpolation-code", + "piece_type": "code_example", + "title": "f-strings for direct interpolation", + "order": 1, + "content": { + "text": "F-strings embed expressions inside {} and are the cleanest way to build output strings.", + "code": "name = 'Jan'\nprint(f'{name} studies Python.')", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-1", + "ks-72dda5450c" + ] + } + ] + }, + { + "id": "output-formatting-must_know-format-still-appears-in-exams", + "title": ".format() still appears in exams", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "kp-4", + "ai-example-4", + "manual-string-format-method" + ], + "pieces": [ + { + "id": "output-formatting-must_know-format-still-appears-in-exams-code", + "piece_type": "code_example", + "title": ".format() still appears in exams", + "order": 1, + "content": { + "text": "The older .format() style still appears in exam questions and supports the same width and precision ideas.", + "code": "name = 'Jan'\nscore = 7\nprint('Student {} scored {:03d}'.format(name, score))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-4", + "ai-example-4", + "manual-string-format-method" + ] + } + ] + }, + { + "id": "output-formatting-must_know-join-plus-a-custom-tail", + "title": "join() plus a custom tail", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "ai-example-5", + "manual-output-formatting-code" + ], + "pieces": [ + { + "id": "output-formatting-must_know-join-plus-a-custom-tail-code", + "piece_type": "code_example", + "title": "join() plus a custom tail", + "order": 1, + "content": { + "text": "Use join() for the repeated separator, then add the final custom wording separately.", + "code": "names = ['Ada', 'Linus', 'Grace']\nprint(', '.join(names[:-1]) + ', and ' + names[-1])", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ai-example-5", + "manual-output-formatting-code" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "output-formatting-exam_patterns-zero-padding-and-decimal-precision", + "title": "Zero padding and decimal precision", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "kp-3", + "ai-example-3", + "kp-5" + ], + "pieces": [ + { + "id": "output-formatting-exam_patterns-zero-padding-and-decimal-precision-code", + "piece_type": "code_example", + "title": "Zero padding and decimal precision", + "order": 1, + "content": { + "text": "Recognize formatting specs like {:03d} for zero padding and {:.1f} for one decimal place.", + "code": "print(f'{7:03d}')\nprint('{:.1f}'.format(7.25))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-3", + "ai-example-3", + "kp-5" + ] + } + ] + }, + { + "id": "output-formatting-exam_patterns-debug-output-with-f-var", + "title": "Debug output with f'{var=}'", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "kp-2", + "ai-example-2" + ], + "pieces": [ + { + "id": "output-formatting-exam_patterns-debug-output-with-f-var-code", + "piece_type": "code_example", + "title": "Debug output with f'{var=}'", + "order": 1, + "content": { + "text": "f'{var=}' prints both the variable name and the current value, which is easy to miss in answer choices.", + "code": "val = 10\nprint(f'{val=}')", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-2", + "ai-example-2" + ] + } + ] + }, + { + "id": "output-formatting-exam_patterns-repeated-output-with", + "title": "Repeated output with *", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "manual-string-repetition" + ], + "pieces": [ + { + "id": "output-formatting-exam_patterns-repeated-output-with-code", + "piece_type": "code_example", + "title": "Repeated output with *", + "order": 1, + "content": { + "text": "The * operator repeats strings and can show up in quick output questions.", + "code": "print('ha' * 3)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-string-repetition" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "output-formatting-useful_backup-legacy-format-width", + "title": "Legacy format width", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "kp-4", + "ai-example-4" + ], + "pieces": [ + { + "id": "output-formatting-useful_backup-legacy-format-width-code", + "piece_type": "code_example", + "title": "Legacy format width", + "order": 1, + "content": { + "text": "'{:04d}'.format(n) is the non-f-string version of zero padding and is still worth recognizing.", + "code": "print('{:04d}'.format(7))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-4", + "ai-example-4" + ] + } + ] + }, + { + "id": "output-formatting-useful_backup-build-the-middle-then-patch-the-tail", + "title": "Build the middle, then patch the tail", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "", + "source_refs": [ + "manual-output-formatting-code" + ], + "pieces": [ + { + "id": "output-formatting-useful_backup-build-the-middle-then-patch-the-tail-code", + "piece_type": "code_example", + "title": "Build the middle, then patch the tail", + "order": 1, + "content": { + "text": "When the last item needs special wording, format the repeated middle first and then patch on the ending.", + "code": "body = ', '.join(names[:-1])", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-output-formatting-code" + ] + } + ] + } + ] + }, + { + "key": "quick_tables", + "title": "Quick Tables", + "description": "", + "initial_visible_count": 1, + "snippets": [ + { + "id": "output-formatting-quick_tables-formatting-mini-table", + "title": "Formatting mini table", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Strings and Output", + "main_topic": "Output Formatting", + "summary": "A small reference for the format specs and output-building patterns that are easiest to forget under pressure.", + "source_refs": [ + "manual-string-format-method", + "manual-output-formatting-code" + ], + "pieces": [ + { + "id": "output-format-mini-table", + "piece_type": "reference_table", + "title": "Output formatting mini table", + "order": 1, + "content": { + "text": "This keeps the highest-value formatting specs in one place.", + "headers": [ + "Pattern", + "Meaning" + ], + "rows": [ + [ + "f'{name}'", + "embed a value directly" + ], + [ + "{:03d}", + "integer with zero padding" + ], + [ + "{:.1f}", + "one decimal place" + ], + [ + "', '.join(names)", + "separator between repeated items" + ], + [ + "f'{var=}'", + "show name and value together" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-string-format-method", + "manual-output-formatting-code" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "pandas-data-work", + "title": "Pandas Data Work", + "summary": "The small set of DataFrame and Series patterns that matter most under exam pressure.", + "source_refs": { + "draft_file": "pandas_data_work.json" + }, + "main_topics": [ + { + "id": "pandas-core-structures", + "title": "Pandas Core Structures", + "summary": "", + "parent_topic": "Pandas Data Work", + "main_week": 5, + "related_weeks": [ + 5 + ], + "topic_order": 16, + "search_text": "Pandas Core Structures Know the three base objects cold: `Series`, `DataFrame`, and the default index A `Series` is one labeled column of data. A `DataFrame` is a 2D table built most often from a dict of equal-length lists. If you do not supply an index, pandas gives `0, 1, 2, ...` automatically. Shape rule that keeps appearing on exams: `df['A']` vs `df[['A']]` `df['A']` returns a `Series` (1D). `df[['A']]` returns a one-column `DataFrame` (2D). Use the list form whenever the question explicitly wants a DataFrame back. Use direct column arithmetic for derived columns before reaching for `map` or `apply` If the task is plain elementwise column math, write the vectorized expression directly. Do not wrap simple column addition or subtraction in `map(...)` or row-wise `apply(...)` unless the question truly needs custom per-value or per-row logic. Creating a new column from existing columns Exam questions repeatedly test whether you understand that new columns are assigned by column name and filled with vectorized Series results. The classic trap: `map` is not a shortcut for vectorized arithmetic `Series.map(...)` expects a function, dict, or mapping-like Series. If the whole expression already works elementwise, use the vectorized form directly. Constructor and selection cheat table A compact table for the constructors and access forms that look similar but return different shapes. Index alignment can silently create `NaN` values When pandas combines Series or DataFrames, it aligns by index labels. If indices do not match, the result can fill with `NaN` instead of doing row-by-row arithmetic by position. DatetimeIndex matters only when the index actually stores dates If the DataFrame index is a `DatetimeIndex`, rows can be filtered using date attributes like `.month`. This is worth keeping as a backup, not a headline rule.", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "pandas-core-structures-must_know-know-the-three-base-objects-cold-series-dataframe-and-the-default-index", + "title": "Know the three base objects cold: `Series`, `DataFrame`, and the default index", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "A `Series` is one labeled column of data. A `DataFrame` is a 2D table built most often from a dict of equal-length lists. If you do not supply an index, pandas gives `0, 1, 2, ...` automatically.", + "source_refs": [ + "manual-pandas-df", + "manual-pandas-import", + "ks-052ed25923", + "ks-9a5d2c05fb" + ], + "pieces": [ + { + "id": "pandas-core-objects-table", + "piece_type": "reference_table", + "title": "Series, DataFrame, and default index", + "order": 1, + "content": { + "text": "A DataFrame is most often built from a dict of equal-length lists.", + "headers": [ + "Object", + "Think of it as", + "Default index if omitted" + ], + "rows": [ + [ + "Series", + "one labeled column", + "0, 1, 2, ..." + ], + [ + "DataFrame", + "2D table of aligned columns", + "0, 1, 2, ..." + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-pandas-df", + "manual-pandas-import", + "ks-052ed25923", + "ks-9a5d2c05fb" + ] + }, + { + "id": "pandas-core-objects-code", + "piece_type": "code_example", + "title": "Know the three base objects cold: `Series`, `DataFrame`, and the default index", + "order": 2, + "content": { + "text": "A `Series` is one labeled column of data. A `DataFrame` is a 2D table built most often from a dict of equal-length lists. If you do not supply an index, pandas gives `0, 1, 2, ...` automatically.", + "code": "import pandas as pd\ns = pd.Series([153, 160, 150], name='Length')\ndf = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-pandas-df", + "manual-pandas-import", + "ks-052ed25923", + "ks-9a5d2c05fb" + ] + } + ] + }, + { + "id": "pandas-core-structures-must_know-shape-rule-that-keeps-appearing-on-exams-df-a-vs-df-a", + "title": "Shape rule that keeps appearing on exams: `df['A']` vs `df[['A']]`", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "`df['A']` returns a `Series` (1D). `df[['A']]` returns a one-column `DataFrame` (2D). Use the list form whenever the question explicitly wants a DataFrame back.", + "source_refs": [ + "manual-series-vs-dataframe", + "kp-manual-series-vs-df-d1" + ], + "pieces": [ + { + "id": "pandas-shape-rules-table", + "piece_type": "reference_table", + "title": "Selection shape rules", + "order": 1, + "content": { + "text": "When the prompt explicitly wants a DataFrame back, keep the selection 2D.", + "headers": [ + "Form", + "Returns", + "Why it matters" + ], + "rows": [ + [ + "df['A']", + "Series", + "one column, 1D" + ], + [ + "df[['A']]", + "DataFrame", + "one-column table, stays 2D" + ], + [ + "df[['A', 'B']]", + "DataFrame", + "multi-column subset" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-series-vs-dataframe", + "kp-manual-series-vs-df-d1" + ] + }, + { + "id": "pandas-shape-rules-code", + "piece_type": "code_example", + "title": "Shape rule that keeps appearing on exams: `df['A']` vs `df[['A']]`", + "order": 2, + "content": { + "text": "`df['A']` returns a `Series` (1D). `df[['A']]` returns a one-column `DataFrame` (2D). Use the list form whenever the question explicitly wants a DataFrame back.", + "code": "df['A'] # Series\ndf[['A']] # one-column DataFrame\ndf[['A', 'B']] # two-column DataFrame", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-series-vs-dataframe", + "kp-manual-series-vs-df-d1" + ] + } + ] + }, + { + "id": "pandas-core-structures-must_know-use-direct-column-arithmetic-for-derived-columns-before-reaching-for-map-or-apply", + "title": "Use direct column arithmetic for derived columns before reaching for `map` or `apply`", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "If the task is plain elementwise column math, write the vectorized expression directly. Do not wrap simple column addition or subtraction in `map(...)` or row-wise `apply(...)` unless the question truly needs custom per-value or per-row logic.", + "source_refs": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet-item-kp-5-d2" + ], + "pieces": [ + { + "id": "pandas-core-structures-must_know-use-direct-column-arithmetic-for-derived-columns-before-reaching-for-map-or-apply-code", + "piece_type": "code_example", + "title": "Use direct column arithmetic for derived columns before reaching for `map` or `apply`", + "order": 1, + "content": { + "text": "", + "code": "df['C'] = df['A'] + df['B']\ndf['D'] = df['A'] - df['B']", + "output": "" + }, + "selectable": true, + "source_refs": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet-item-kp-5-d2" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "pandas-core-structures-exam_patterns-creating-a-new-column-from-existing-columns", + "title": "Creating a new column from existing columns", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "Exam questions repeatedly test whether you understand that new columns are assigned by column name and filled with vectorized Series results.", + "source_refs": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ], + "pieces": [ + { + "id": "pandas-core-structures-exam_patterns-creating-a-new-column-from-existing-columns-code", + "piece_type": "code_example", + "title": "Creating a new column from existing columns", + "order": 1, + "content": { + "text": "Watch out: Do not write `df['A' + 'B']`.; Do not use a row label like `df.loc['C']` when the goal is a new column.", + "code": "df['C'] = df['A'] + df['B']\n# or\ndf.loc[:, 'C'] = df.loc[:, 'A'] + df.loc[:, 'B']", + "output": "" + }, + "selectable": true, + "source_refs": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ] + }, + { + "id": "pandas-core-structures-exam_patterns-the-classic-trap-map-is-not-a-shortcut-for-vectorized-arithmetic", + "title": "The classic trap: `map` is not a shortcut for vectorized arithmetic", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "`Series.map(...)` expects a function, dict, or mapping-like Series. If the whole expression already works elementwise, use the vectorized form directly.", + "source_refs": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "kp-5" + ], + "pieces": [ + { + "id": "pandas-core-structures-exam_patterns-the-classic-trap-map-is-not-a-shortcut-for-vectorized-arithmetic-code", + "piece_type": "code_example", + "title": "The classic trap: `map` is not a shortcut for vectorized arithmetic", + "order": 1, + "content": { + "text": "", + "code": "(s - s.mean())**2", + "output": "" + }, + "selectable": true, + "source_refs": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "kp-5" + ] + } + ] + }, + { + "id": "pandas-core-structures-exam_patterns-constructor-and-selection-cheat-table", + "title": "Constructor and selection cheat table", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "A compact table for the constructors and access forms that look similar but return different shapes.", + "source_refs": [ + "manual-pandas-df", + "manual-series-vs-dataframe" + ], + "pieces": [ + { + "id": "pandas-construct-select-table", + "piece_type": "reference_table", + "title": "Constructor and selection cheat table", + "order": 1, + "content": { + "text": "This gives you the constructor and shape rules in one glance.", + "headers": [ + "Pattern", + "Use it for" + ], + "rows": [ + [ + "pd.Series([10, 20, 30])", + "one labeled column" + ], + [ + "pd.DataFrame({'A': [1, 2], 'B': [3, 4]})", + "2D table" + ], + [ + "df['A']", + "one column as Series" + ], + [ + "df[['A']]", + "one-column DataFrame" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-pandas-df", + "manual-series-vs-dataframe" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "pandas-core-structures-useful_backup-index-alignment-can-silently-create-nan-values", + "title": "Index alignment can silently create `NaN` values", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "When pandas combines Series or DataFrames, it aligns by index labels. If indices do not match, the result can fill with `NaN` instead of doing row-by-row arithmetic by position.", + "source_refs": [ + "cs-b069af91f4" + ], + "pieces": [ + { + "id": "pandas-core-structures-useful_backup-index-alignment-can-silently-create-nan-values-code", + "piece_type": "code_example", + "title": "Index alignment can silently create `NaN` values", + "order": 1, + "content": { + "text": "", + "code": "df2 += pd.DataFrame({'A': [2, 5, 6], 'B': [3, 4, 7]}, index=[4, 5, 6])", + "output": "" + }, + "selectable": true, + "source_refs": [ + "cs-b069af91f4" + ] + } + ] + }, + { + "id": "pandas-core-structures-useful_backup-datetimeindex-matters-only-when-the-index-actually-stores-dates", + "title": "DatetimeIndex matters only when the index actually stores dates", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Pandas Core Structures", + "summary": "If the DataFrame index is a `DatetimeIndex`, rows can be filtered using date attributes like `.month`. This is worth keeping as a backup, not a headline rule.", + "source_refs": [ + "ks-75cf35c8b4" + ], + "pieces": [ + { + "id": "pandas-core-structures-useful_backup-datetimeindex-matters-only-when-the-index-actually-stores-dates-code", + "piece_type": "code_example", + "title": "DatetimeIndex matters only when the index actually stores dates", + "order": 1, + "content": { + "text": "", + "code": "df.loc[[r for r in df.index if r.month == 4]]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ks-75cf35c8b4" + ] + } + ] + } + ] + } + ] + }, + { + "id": "inspecting-and-selecting-data", + "title": "Inspecting and Selecting Data", + "summary": "", + "parent_topic": "Pandas Data Work", + "main_week": 5, + "related_weeks": [ + 5 + ], + "topic_order": 17, + "search_text": "Inspecting and Selecting Data Selection rule in one sentence: plain `df[...]` is not for two axes Use plain `df[...]` for column selection or a boolean row mask. The moment both a row selector and a column selector appear, switch to `.loc[row_sel, col_sel]` or `.iloc[row_sel, col_sel]`. Know the `loc` vs `iloc` slicing difference exactly `.loc` is label-based and includes the stop label in a slice. `.iloc` is integer-position based and excludes the stop position, like normal Python slicing. Selection shape is part of the answer, not a side detail A scalar selector often collapses the result to a `Series`; wrapping labels in a list usually keeps a `DataFrame`. When the prompt says 'return a DataFrame', preserve 2D shape intentionally. Valid vs invalid two-axis selection This is the table that helps you reject impossible pandas indexing forms immediately. Select one column for rows that satisfy a row rule Build the row condition first, then choose the target column(s). If the task wants a DataFrame, keep the column selector as a list. Boolean mask plus explicit columns is the safest exam default When the prompt mixes filtering and selection, `df.loc[mask, columns]` is usually the clearest and least error-prone form. Quick inspection helpers Use `.head(n)` and `.tail(n)` to inspect rows and `.describe()` for summary statistics. These are useful, but they should stay backup material rather than taking premium UI space.", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 4, + "snippets": [ + { + "id": "inspecting-and-selecting-data-must_know-selection-rule-in-one-sentence-plain-df-is-not-for-two-axes", + "title": "Selection rule in one sentence: plain `df[...]` is not for two axes", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Inspecting and Selecting Data", + "summary": "Use plain `df[...]` for column selection or a boolean row mask. The moment both a row selector and a column selector appear, switch to `.loc[row_sel, col_sel]` or `.iloc[row_sel, col_sel]`.", + "source_refs": [ + "manual-pandas-selection", + "kp-manual-pandas-two-axis-d1", + "kp-6" + ], + "pieces": [ + { + "id": "inspecting-and-selecting-data-must_know-selection-rule-in-one-sentence-plain-df-is-not-for-two-axes-code", + "piece_type": "code_example", + "title": "Selection rule in one sentence: plain `df[...]` is not for two axes", + "order": 1, + "content": { + "text": "", + "code": "df['A']\ndf[df['A'] > 0]\ndf.loc[2:4, ['B']]\ndf.iloc[1:4, [1]]\n# not: df[2, 'B']", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-pandas-selection", + "kp-manual-pandas-two-axis-d1", + "kp-6" + ] + } + ] + }, + { + "id": "inspecting-and-selecting-data-must_know-know-the-loc-vs-iloc-slicing-difference-exactly", + "title": "Know the `loc` vs `iloc` slicing difference exactly", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Inspecting and Selecting Data", + "summary": "`.loc` is label-based and includes the stop label in a slice. `.iloc` is integer-position based and excludes the stop position, like normal Python slicing.", + "source_refs": [ + "manual-pandas-selection", + "ks-57ff66f9f1", + "ks-dfc064979d" + ], + "pieces": [ + { + "id": "inspecting-and-selecting-data-must_know-know-the-loc-vs-iloc-slicing-difference-exactly-code", + "piece_type": "code_example", + "title": "Know the `loc` vs `iloc` slicing difference exactly", + "order": 1, + "content": { + "text": "", + "code": "df.loc['First':'Third', ['Name', 'Weight']]\ndf.iloc[0:2, 0:1]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-pandas-selection", + "ks-57ff66f9f1", + "ks-dfc064979d" + ] + } + ] + }, + { + "id": "inspecting-and-selecting-data-must_know-selection-shape-is-part-of-the-answer-not-a-side-detail", + "title": "Selection shape is part of the answer, not a side detail", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Inspecting and Selecting Data", + "summary": "A scalar selector often collapses the result to a `Series`; wrapping labels in a list usually keeps a `DataFrame`. When the prompt says 'return a DataFrame', preserve 2D shape intentionally.", + "source_refs": [ + "ks-99fe849762", + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ], + "pieces": [ + { + "id": "inspecting-and-selecting-data-must_know-selection-shape-is-part-of-the-answer-not-a-side-detail-code", + "piece_type": "code_example", + "title": "Selection shape is part of the answer, not a side detail", + "order": 1, + "content": { + "text": "", + "code": "df.loc[2] # Series\ndf.loc[[2]] # DataFrame\ndf.loc[df.index % 2 == 0, ['B']] # DataFrame, not Series", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ks-99fe849762", + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ] + }, + { + "id": "inspecting-and-selecting-data-must_know-valid-vs-invalid-two-axis-selection", + "title": "Valid vs invalid two-axis selection", + "order": 4, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Inspecting and Selecting Data", + "summary": "This is the table that helps you reject impossible pandas indexing forms immediately.", + "source_refs": [ + "manual-pandas-selection", + "kp-manual-pandas-two-axis-d1" + ], + "pieces": [ + { + "id": "pandas-valid-invalid-table", + "piece_type": "reference_table", + "title": "Valid vs invalid selection forms", + "order": 1, + "content": { + "text": "Switch to `.loc[...]` or `.iloc[...]` as soon as you need both rows and columns.", + "headers": [ + "Code", + "Valid?", + "Meaning" + ], + "rows": [ + [ + "df.loc[2:4, ['B']]", + "yes", + "label-based rows + named columns" + ], + [ + "df.iloc[1:4, [1]]", + "yes", + "position-based rows + columns" + ], + [ + "df.loc[df['A'] > 0, ['B', 'C']]", + "yes", + "boolean mask rows + named columns" + ], + [ + "df[df['A'] > 0]", + "yes", + "row filtering only" + ], + [ + "df[2, 'B']", + "no", + "plain df[...] is not for two axes" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-pandas-selection", + "kp-manual-pandas-two-axis-d1" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "inspecting-and-selecting-data-exam_patterns-select-one-column-for-rows-that-satisfy-a-row-rule", + "title": "Select one column for rows that satisfy a row rule", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Inspecting and Selecting Data", + "summary": "Build the row condition first, then choose the target column(s). If the task wants a DataFrame, keep the column selector as a list.", + "source_refs": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ], + "pieces": [ + { + "id": "inspecting-and-selecting-data-exam_patterns-select-one-column-for-rows-that-satisfy-a-row-rule-code", + "piece_type": "code_example", + "title": "Select one column for rows that satisfy a row rule", + "order": 1, + "content": { + "text": "Watch out: `df.loc[2::2, 'B']` may return a Series instead of the required DataFrame.; `df[2, 4, 6, 'B']` is invalid.", + "code": "df.loc[df.index % 2 == 0, ['B']]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ] + }, + { + "id": "inspecting-and-selecting-data-exam_patterns-boolean-mask-plus-explicit-columns-is-the-safest-exam-default", + "title": "Boolean mask plus explicit columns is the safest exam default", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Inspecting and Selecting Data", + "summary": "When the prompt mixes filtering and selection, `df.loc[mask, columns]` is usually the clearest and least error-prone form.", + "source_refs": [ + "manual-pandas-selection", + "ai-example-8", + "kp-5" + ], + "pieces": [ + { + "id": "inspecting-and-selecting-data-exam_patterns-boolean-mask-plus-explicit-columns-is-the-safest-exam-default-code", + "piece_type": "code_example", + "title": "Boolean mask plus explicit columns is the safest exam default", + "order": 1, + "content": { + "text": "", + "code": "mask = df['A'] > 0\nresult = df.loc[mask, ['B', 'C']]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-pandas-selection", + "ai-example-8", + "kp-5" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "inspecting-and-selecting-data-useful_backup-quick-inspection-helpers", + "title": "Quick inspection helpers", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Inspecting and Selecting Data", + "summary": "Use `.head(n)` and `.tail(n)` to inspect rows and `.describe()` for summary statistics. These are useful, but they should stay backup material rather than taking premium UI space.", + "source_refs": [ + "ai-example-1", + "ks-0114a2cff0" + ], + "pieces": [ + { + "id": "inspecting-and-selecting-data-useful_backup-quick-inspection-helpers-code", + "piece_type": "code_example", + "title": "Quick inspection helpers", + "order": 1, + "content": { + "text": "", + "code": "df.head(3)\ndf.tail(2)\ndf.describe()", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ai-example-1", + "ks-0114a2cff0" + ] + } + ] + } + ] + } + ] + }, + { + "id": "working-with-values", + "title": "Working With Values", + "summary": "", + "parent_topic": "Pandas Data Work", + "main_week": 5, + "related_weeks": [ + 5 + ], + "topic_order": 18, + "search_text": "Working With Values Default mental model: vectorized column expressions first, `map`/`apply` only when needed If the job is straightforward arithmetic or string work that pandas already supports elementwise, write the expression directly. Use `Series.map(...)` for one value in -> one value out on a single Series. Use `DataFrame.apply(..., axis=1)` only when the logic genuinely needs multiple columns from the same row. Filter first, then aggregate or sort A very common exam pattern is: build a mask, select rows or one column, then run `sum()`, `mean()`, `count()`, or `sort_values(...)` on the result. Use the vectorized text tools pandas already gives you Use `.str` methods for built-in string operations over a whole Series, and `isin(...)` for membership tests over many values at once. Choose between vectorized math, `map`, and `apply` with a quick table This restores one of the high-value decision aids that is easy to scan under exam pressure. Text splitting: choose output shape on purpose If you want one derived Series, `map(...)` can be enough. If you want multiple new DataFrame columns, use `.str.split(..., expand=True)`. Missing values: decide whether to keep shape or drop data Use `.fillna(...)` if you want to preserve the table and replace missing values. Use `.dropna()` when incomplete rows or columns should disappear entirely. Sorting and scalar broadcasting are good support patterns, not front-page content Keep `sort_values(...)` vs `sort_index(...)` and scalar broadcasting in reserve because they matter, but they are less often the decisive snippet than filtering, shape, and map/apply decisions.", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 4, + "snippets": [ + { + "id": "working-with-values-must_know-default-mental-model-vectorized-column-expressions-first-map-apply-only-when-needed", + "title": "Default mental model: vectorized column expressions first, `map`/`apply` only when needed", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Working With Values", + "summary": "If the job is straightforward arithmetic or string work that pandas already supports elementwise, write the expression directly. Use `Series.map(...)` for one value in -> one value out on a single Series. Use `DataFrame.apply(..., axis=1)` only when the logic genuinely needs multiple columns from the same row.", + "source_refs": [ + "manual-pandas-values", + "kp-5-d2", + "kp-5", + "kp-6" + ], + "pieces": [ + { + "id": "working-with-values-must_know-default-mental-model-vectorized-column-expressions-first-map-apply-only-when-needed-code", + "piece_type": "code_example", + "title": "Default mental model: vectorized column expressions first, `map`/`apply` only when needed", + "order": 1, + "content": { + "text": "", + "code": "df['total'] = df['A'] + df['B']\ns.map(lambda x: x + 1)\ndf.apply(lambda row: row['A'] + row['B'], axis=1)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-pandas-values", + "kp-5-d2", + "kp-5", + "kp-6" + ] + } + ] + }, + { + "id": "working-with-values-must_know-filter-first-then-aggregate-or-sort", + "title": "Filter first, then aggregate or sort", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Working With Values", + "summary": "A very common exam pattern is: build a mask, select rows or one column, then run `sum()`, `mean()`, `count()`, or `sort_values(...)` on the result.", + "source_refs": [ + "manual-pandas-filter-aggregate", + "kp-manual-filter-aggregate-d2", + "manual-pandas-values" + ], + "pieces": [ + { + "id": "working-with-values-must_know-filter-first-then-aggregate-or-sort-code", + "piece_type": "code_example", + "title": "Filter first, then aggregate or sort", + "order": 1, + "content": { + "text": "", + "code": "mask = df['A'] > 0\nresult = df.loc[mask, 'B'].mean()\ndf.sort_values('B', ascending=False)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-pandas-filter-aggregate", + "kp-manual-filter-aggregate-d2", + "manual-pandas-values" + ] + } + ] + }, + { + "id": "working-with-values-must_know-use-the-vectorized-text-tools-pandas-already-gives-you", + "title": "Use the vectorized text tools pandas already gives you", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Working With Values", + "summary": "Use `.str` methods for built-in string operations over a whole Series, and `isin(...)` for membership tests over many values at once.", + "source_refs": [ + "ks-115ab52188", + "ks-2bed6c308f", + "kp-3", + "kp-4" + ], + "pieces": [ + { + "id": "working-with-values-must_know-use-the-vectorized-text-tools-pandas-already-gives-you-code", + "piece_type": "code_example", + "title": "Use the vectorized text tools pandas already gives you", + "order": 1, + "content": { + "text": "", + "code": "s.str.upper().str.count('A')\ndf[df['city'].isin(['A', 'B'])]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ks-115ab52188", + "ks-2bed6c308f", + "kp-3", + "kp-4" + ] + } + ] + }, + { + "id": "working-with-values-must_know-choose-between-vectorized-math-map-and-apply-with-a-quick-table", + "title": "Choose between vectorized math, `map`, and `apply` with a quick table", + "order": 4, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Working With Values", + "summary": "This restores one of the high-value decision aids that is easy to scan under exam pressure.", + "source_refs": [ + "manual-pandas-values", + "kp-5", + "kp-6" + ], + "pieces": [ + { + "id": "pandas-map-apply-table", + "piece_type": "reference_table", + "title": "Value-transformation decision table", + "order": 1, + "content": { + "text": "Use the simplest shape-preserving option that matches the task.", + "headers": [ + "Need", + "Use", + "Example" + ], + "rows": [ + [ + "simple column arithmetic", + "vectorized expression", + "df['A'] + df['B']" + ], + [ + "one value in -> one value out on a Series", + "Series.map(...)", + "s.map(lambda x: x + 1)" + ], + [ + "row logic using multiple columns", + "DataFrame.apply(..., axis=1)", + "df.apply(lambda row: row['A'] + row['B'], axis=1)" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-pandas-values", + "kp-5", + "kp-6" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "working-with-values-exam_patterns-text-splitting-choose-output-shape-on-purpose", + "title": "Text splitting: choose output shape on purpose", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Working With Values", + "summary": "If you want one derived Series, `map(...)` can be enough. If you want multiple new DataFrame columns, use `.str.split(..., expand=True)`.", + "source_refs": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "manual-pandas-split-into-columns" + ], + "pieces": [ + { + "id": "working-with-values-exam_patterns-text-splitting-choose-output-shape-on-purpose-code", + "piece_type": "code_example", + "title": "Text splitting: choose output shape on purpose", + "order": 1, + "content": { + "text": "Watch out: Do not treat `Series.split(...)` as if pandas strings worked like plain Python strings.; Choose `expand=True` only when the target is multiple columns.", + "code": "s.map(lambda x: x.split('; ')[0])\n# or\ndf[['municipality', 'province']] = df['place'].str.split('; ', expand=True)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "manual-pandas-split-into-columns" + ] + } + ] + }, + { + "id": "working-with-values-exam_patterns-missing-values-decide-whether-to-keep-shape-or-drop-data", + "title": "Missing values: decide whether to keep shape or drop data", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Working With Values", + "summary": "Use `.fillna(...)` if you want to preserve the table and replace missing values. Use `.dropna()` when incomplete rows or columns should disappear entirely.", + "source_refs": [ + "kp-manual-drop-missing", + "ks-18a9645168" + ], + "pieces": [ + { + "id": "working-with-values-exam_patterns-missing-values-decide-whether-to-keep-shape-or-drop-data-code", + "piece_type": "code_example", + "title": "Missing values: decide whether to keep shape or drop data", + "order": 1, + "content": { + "text": "", + "code": "df.fillna('No value')\ndf.dropna()", + "output": "" + }, + "selectable": true, + "source_refs": [ + "kp-manual-drop-missing", + "ks-18a9645168" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 1, + "snippets": [ + { + "id": "working-with-values-useful_backup-sorting-and-scalar-broadcasting-are-good-support-patterns-not-front-page-content", + "title": "Sorting and scalar broadcasting are good support patterns, not front-page content", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Pandas Data Work", + "main_topic": "Working With Values", + "summary": "Keep `sort_values(...)` vs `sort_index(...)` and scalar broadcasting in reserve because they matter, but they are less often the decisive snippet than filtering, shape, and map/apply decisions.", + "source_refs": [ + "ai-example-1", + "ai-example-2", + "ks-f8eec928e1" + ], + "pieces": [ + { + "id": "working-with-values-useful_backup-sorting-and-scalar-broadcasting-are-good-support-patterns-not-front-page-content-code", + "piece_type": "code_example", + "title": "Sorting and scalar broadcasting are good support patterns, not front-page content", + "order": 1, + "content": { + "text": "", + "code": "df.sort_values(by='score', ascending=False)\ndf['Height'] += 10", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ai-example-1", + "ai-example-2", + "ks-f8eec928e1" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "datetime-and-time-logic", + "title": "Datetime and Time Logic", + "summary": "Parsing, formatting, and doing date arithmetic without turning datetimes into strings too early.", + "source_refs": { + "draft_file": "datetime_and_oop.json" + }, + "main_topics": [ + { + "id": "datetime-parsing-and-formatting", + "title": "Datetime Parsing and Formatting", + "summary": "Parsing date text into datetime objects, formatting datetime objects back into strings, and remembering the small set of format codes that actually shows up in exams.", + "parent_topic": "Datetime and Time Logic", + "main_week": 6, + "related_weeks": [ + 6 + ], + "topic_order": 19, + "search_text": "Datetime Parsing and Formatting Parsing date text into datetime objects, formatting datetime objects back into strings, and remembering the small set of format codes that actually shows up in exams. Parse first, format last `datetime.strptime(text, format)` turns text into a datetime object; `dt.strftime(format)` turns a datetime object into text. Do math and attribute access while it is still a datetime object. Know the exam format codes by sight The recurring codes are `%Y` year, `%y` 2-digit year, `%m` month, `%d` day, `%H` hour, `%M` minute, `%S` second, and `%j` day-of-year. Constructor order is year, month, day. Object vs string mental model A parsed datetime supports `.year`, `.month`, comparisons, and arithmetic. A formatted string does not. If an option formats too early, it usually breaks the later arithmetic step. Decode the date format from the sample string If the question shows both the input string and the format template, match separators and positions directly. This is usually enough to identify the month/day/year meaning without extra theory. Day-of-year questions use one of two routes Either use `%j` when formatting, or compute `(dt - datetime(dt.year, 1, 1)).days + 1`. Exam distractors often forget the `+ 1` or return a timedelta instead of an integer. DataFrame date-column questions still reduce to parse/format rules When a question builds a `Date` column from day, month, and year pieces, the winning option usually constructs a datetime in year-month-day order and then formats it with `strftime`. `replace()` returns a new datetime Datetime objects are immutable. `replace(...)` gives you a modified copy; it does not change the original object in place. `now()`, `timestamp()`, and ISO helpers These are fine references to have nearby, but they are backup material here because they are lower-frequency than parse/format and arithmetic traps. Weekday, month, and year attributes are direct lookups Once you have a datetime object, use attributes like `.year`, `.month`, `.day`, and `.weekday()` directly instead of re-formatting the date string.", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "datetime-parsing-and-formatting-must_know-parse-first-format-last", + "title": "Parse first, format last", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "`datetime.strptime(text, format)` turns text into a datetime object; `dt.strftime(format)` turns a datetime object into text. Do math and attribute access while it is still a datetime object.", + "source_refs": [ + "manual-datetime-parse-format", + "snippet-item-manual-strftime-vs-strptime", + "kp-manual-datetime-objects-vs-strings" + ], + "pieces": [ + { + "id": "dt-parse-vs-format-table", + "piece_type": "reference_table", + "title": "Parse vs format", + "order": 1, + "content": { + "text": "Do arithmetic and attribute access while the value is still a datetime object.", + "headers": [ + "Call", + "Input", + "Output" + ], + "rows": [ + [ + "datetime.strptime(text, fmt)", + "string + format", + "datetime object" + ], + [ + "dt.strftime(fmt)", + "datetime object + format", + "string" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-datetime-parse-format", + "snippet-item-manual-strftime-vs-strptime", + "kp-manual-datetime-objects-vs-strings" + ] + }, + { + "id": "dt-parse-vs-format-code", + "piece_type": "code_example", + "title": "Parse first, format last", + "order": 2, + "content": { + "text": "`datetime.strptime(text, format)` turns text into a datetime object; `dt.strftime(format)` turns a datetime object into text. Do math and attribute access while it is still a datetime object.", + "code": "from datetime import datetime\nstart = datetime.strptime('20-05-2024', '%d-%m-%Y')\nprint(start.strftime('%Y/%m/%d'))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-datetime-parse-format", + "snippet-item-manual-strftime-vs-strptime", + "kp-manual-datetime-objects-vs-strings" + ] + } + ] + }, + { + "id": "datetime-parsing-and-formatting-must_know-know-the-exam-format-codes-by-sight", + "title": "Know the exam format codes by sight", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "The recurring codes are `%Y` year, `%y` 2-digit year, `%m` month, `%d` day, `%H` hour, `%M` minute, `%S` second, and `%j` day-of-year. Constructor order is year, month, day.", + "source_refs": [ + "snippet-item-kp-manual-datetime-format-codes-d1", + "snippet-item-kp-manual-datetime-format-codes", + "ks-169cc25be1", + "ks-755c23c4be" + ], + "pieces": [ + { + "id": "dt-format-codes-table", + "piece_type": "reference_table", + "title": "Format codes you should recognize instantly", + "order": 1, + "content": { + "text": "Constructor order is year, month, day. Formatting codes are read literally in exam answer options.", + "headers": [ + "Code", + "Meaning", + "Example" + ], + "rows": [ + [ + "%Y", + "4-digit year", + "2024" + ], + [ + "%y", + "2-digit year", + "24" + ], + [ + "%m", + "month number", + "03" + ], + [ + "%d", + "day of month", + "09" + ], + [ + "%H", + "hour (24h)", + "17" + ], + [ + "%M", + "minute", + "05" + ], + [ + "%S", + "second", + "42" + ], + [ + "%j", + "day of year", + "060" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-item-kp-manual-datetime-format-codes-d1", + "snippet-item-kp-manual-datetime-format-codes", + "ks-169cc25be1", + "ks-755c23c4be" + ] + }, + { + "id": "dt-format-codes-code", + "piece_type": "code_example", + "title": "Parse then format with the same mental map", + "order": 2, + "content": { + "text": "The recurring codes are `%Y` year, `%y` 2-digit year, `%m` month, `%d` day, `%H` hour, `%M` minute, `%S` second, and `%j` day-of-year. Constructor order is year, month, day.", + "code": "dt = datetime.strptime('2023/1/10', '%Y/%m/%d')\nprint(dt.strftime('%d-%m-%Y')) # 10-01-2023", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-item-kp-manual-datetime-format-codes-d1", + "snippet-item-kp-manual-datetime-format-codes", + "ks-169cc25be1", + "ks-755c23c4be" + ] + } + ] + }, + { + "id": "datetime-parsing-and-formatting-must_know-object-vs-string-mental-model", + "title": "Object vs string mental model", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "A parsed datetime supports `.year`, `.month`, comparisons, and arithmetic. A formatted string does not. If an option formats too early, it usually breaks the later arithmetic step.", + "source_refs": [ + "snippet-item-kp-manual-datetime-objects-vs-strings-d1", + "snippet-item-kp-manual-datetime-objects-vs-strings" + ], + "pieces": [ + { + "id": "datetime-parsing-and-formatting-must_know-object-vs-string-mental-model-code", + "piece_type": "code_example", + "title": "Object vs string mental model", + "order": 1, + "content": { + "text": "", + "code": "dt = datetime.strptime('01-06-2023 09:30', '%d-%m-%Y %H:%M')\ntext = dt.strftime('%d-%m-%Y %H:%M')\n# dt + timedelta(minutes=20) works\n# text + timedelta(minutes=20) does not", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-item-kp-manual-datetime-objects-vs-strings-d1", + "snippet-item-kp-manual-datetime-objects-vs-strings" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "datetime-parsing-and-formatting-exam_patterns-decode-the-date-format-from-the-sample-string", + "title": "Decode the date format from the sample string", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "If the question shows both the input string and the format template, match separators and positions directly. This is usually enough to identify the month/day/year meaning without extra theory.", + "source_refs": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ], + "pieces": [ + { + "id": "dt-decode-format-table", + "piece_type": "reference_table", + "title": "Read the sample string literally", + "order": 1, + "content": { + "text": "Match separators and positions directly; that is usually enough to eliminate the wrong options.", + "headers": [ + "Sample", + "Format", + "Meaning" + ], + "rows": [ + [ + "03/02/2013", + "%m/%d/%Y", + "month 3, day 2, year 2013" + ], + [ + "03-02-2013", + "%d-%m-%Y", + "day 3, month 2, year 2013" + ] + ] + }, + "selectable": true, + "source_refs": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ] + }, + { + "id": "datetime-parsing-and-formatting-exam_patterns-day-of-year-questions-use-one-of-two-routes", + "title": "Day-of-year questions use one of two routes", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "Either use `%j` when formatting, or compute `(dt - datetime(dt.year, 1, 1)).days + 1`. Exam distractors often forget the `+ 1` or return a timedelta instead of an integer.", + "source_refs": [ + "snippet-item-manual-day-of-year", + "snippet-item-kp-manual-datetime-day-of-year", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ], + "pieces": [ + { + "id": "datetime-parsing-and-formatting-exam_patterns-day-of-year-questions-use-one-of-two-routes-code", + "piece_type": "code_example", + "title": "Day-of-year questions use one of two routes", + "order": 1, + "content": { + "text": "", + "code": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-item-manual-day-of-year", + "snippet-item-kp-manual-datetime-day-of-year", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ] + }, + { + "id": "datetime-parsing-and-formatting-exam_patterns-dataframe-date-column-questions-still-reduce-to-parse-format-rules", + "title": "DataFrame date-column questions still reduce to parse/format rules", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "When a question builds a `Date` column from day, month, and year pieces, the winning option usually constructs a datetime in year-month-day order and then formats it with `strftime`.", + "source_refs": [ + "snippet-subtopic-w6-datetime-w6-datetime-core" + ], + "pieces": [ + { + "id": "datetime-parsing-and-formatting-exam_patterns-dataframe-date-column-questions-still-reduce-to-parse-format-rules-code", + "piece_type": "code_example", + "title": "DataFrame date-column questions still reduce to parse/format rules", + "order": 1, + "content": { + "text": "", + "code": "datetime(y, m, d).strftime('%d-%m-%Y')", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "datetime-parsing-and-formatting-useful_backup-replace-returns-a-new-datetime", + "title": "`replace()` returns a new datetime", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "Datetime objects are immutable. `replace(...)` gives you a modified copy; it does not change the original object in place.", + "source_refs": [ + "ks-662456da41", + "snippet-item-kp-manual-datetime-replace" + ], + "pieces": [ + { + "id": "datetime-parsing-and-formatting-useful_backup-replace-returns-a-new-datetime-code", + "piece_type": "code_example", + "title": "`replace()` returns a new datetime", + "order": 1, + "content": { + "text": "", + "code": "d = datetime.now()\nd2 = d.replace(year=2026)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ks-662456da41", + "snippet-item-kp-manual-datetime-replace" + ] + } + ] + }, + { + "id": "datetime-parsing-and-formatting-useful_backup-now-timestamp-and-iso-helpers", + "title": "`now()`, `timestamp()`, and ISO helpers", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "These are fine references to have nearby, but they are backup material here because they are lower-frequency than parse/format and arithmetic traps.", + "source_refs": [ + "ks-e643ee5e77", + "snippet-item-kp-manual-datetime-now", + "snippet-item-kp-manual-datetime-iso" + ], + "pieces": [ + { + "id": "datetime-parsing-and-formatting-useful_backup-now-timestamp-and-iso-helpers-code", + "piece_type": "code_example", + "title": "`now()`, `timestamp()`, and ISO helpers", + "order": 1, + "content": { + "text": "", + "code": "datetime.now().timestamp()\nd.isoformat()\nd.isocalendar()", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ks-e643ee5e77", + "snippet-item-kp-manual-datetime-now", + "snippet-item-kp-manual-datetime-iso" + ] + } + ] + }, + { + "id": "datetime-parsing-and-formatting-useful_backup-weekday-month-and-year-attributes-are-direct-lookups", + "title": "Weekday, month, and year attributes are direct lookups", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Parsing and Formatting", + "summary": "Once you have a datetime object, use attributes like `.year`, `.month`, `.day`, and `.weekday()` directly instead of re-formatting the date string.", + "source_refs": [ + "manual-datetime-parse-format" + ], + "pieces": [ + { + "id": "dt-attributes-table", + "piece_type": "reference_table", + "title": "Direct datetime attributes", + "order": 1, + "content": { + "text": "Use attributes on the datetime object itself; do not format to text first unless the question wants text output.", + "headers": [ + "Attribute / call", + "Returns" + ], + "rows": [ + [ + "dt.year", + "integer year" + ], + [ + "dt.month", + "integer month" + ], + [ + "dt.day", + "integer day" + ], + [ + "dt.weekday()", + "0=Monday ... 6=Sunday" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-datetime-parse-format" + ] + } + ] + } + ] + } + ] + }, + { + "id": "datetime-arithmetic-and-comparisons", + "title": "Datetime Arithmetic and Comparisons", + "summary": "Timedelta arithmetic, overlap/comparison logic, and the specific traps that show up when an option turns a datetime into text too early.", + "parent_topic": "Datetime and Time Logic", + "main_week": 6, + "related_weeks": [ + 6 + ], + "topic_order": 20, + "search_text": "Datetime Arithmetic and Comparisons Timedelta arithmetic, overlap/comparison logic, and the specific traps that show up when an option turns a datetime into text too early. Do arithmetic before formatting Add or subtract `timedelta(...)` while the value is a datetime object. Only call `strftime(...)` after the arithmetic is finished. Subtracting datetimes gives a timedelta The result of `end - start` is a `timedelta`, not another datetime. The most exam-useful attribute is usually `.days`. Datetime comparisons behave like normal ordering You can compare datetimes with `<`, `>`, and `==`. Overlap questions usually combine two comparisons: one start must be before the other end, and one end must be after the other start. The classic trap: `strftime` too early A wrong option often stores the formatted string in a list and then tries to add another week to that string in the next loop iteration. Overlap logic is interval logic, not equality logic For event-overlap questions, the winning answer is usually the one that checks interval intersection, not exact matching times. Constructor-vs-format confusion is a common distractor Wrong options often swap constructor order, misuse `strftime` where `strptime` is needed, or try to do datetime math on a string result. Build recurring schedules by advancing the datetime, not the string For repeated appointments or weekly schedules, keep a datetime in the loop, append the formatted text only at the edge, and advance the datetime with a timedelta each iteration. Timedelta stores `days`, `seconds`, and `microseconds` directly This is sometimes useful for eliminating distractors that refer to nonexistent direct attributes like `hours`. You can derive day-of-year without `%j` Keep this around as a fallback mental model when the format-code route is not obvious.", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "datetime-arithmetic-and-comparisons-must_know-do-arithmetic-before-formatting", + "title": "Do arithmetic before formatting", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "Add or subtract `timedelta(...)` while the value is a datetime object. Only call `strftime(...)` after the arithmetic is finished.", + "source_refs": [ + "manual-datetime-arithmetic", + "kp-manual-datetime-objects-vs-strings" + ], + "pieces": [ + { + "id": "datetime-arithmetic-and-comparisons-must_know-do-arithmetic-before-formatting-code", + "piece_type": "code_example", + "title": "Do arithmetic before formatting", + "order": 1, + "content": { + "text": "", + "code": "from datetime import datetime, timedelta\nstart = datetime.strptime('2024-05-20', '%Y-%m-%d')\nnext_week = start + timedelta(days=7)\nprint(next_week.strftime('%Y-%m-%d'))", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-datetime-arithmetic", + "kp-manual-datetime-objects-vs-strings" + ] + } + ] + }, + { + "id": "datetime-arithmetic-and-comparisons-must_know-subtracting-datetimes-gives-a-timedelta", + "title": "Subtracting datetimes gives a timedelta", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "The result of `end - start` is a `timedelta`, not another datetime. The most exam-useful attribute is usually `.days`.", + "source_refs": [ + "ks-86cd7ede1c", + "snippet-item-kp-manual-datetime-delta", + "snippet-item-manual-timedelta-attrs" + ], + "pieces": [ + { + "id": "dt-delta-table", + "piece_type": "reference_table", + "title": "Datetime subtraction and timedelta facts", + "order": 1, + "content": { + "text": "The most exam-useful timedelta attribute is usually `.days`.", + "headers": [ + "Expression", + "Result" + ], + "rows": [ + [ + "end - start", + "timedelta" + ], + [ + "start + timedelta(days=7)", + "datetime" + ], + [ + "diff.days", + "whole-day count" + ], + [ + "timedelta(hours=2, minutes=30)", + "2.5 hours" + ] + ] + }, + "selectable": true, + "source_refs": [ + "ks-86cd7ede1c", + "snippet-item-kp-manual-datetime-delta", + "snippet-item-manual-timedelta-attrs" + ] + }, + { + "id": "dt-delta-code", + "piece_type": "code_example", + "title": "Subtracting datetimes gives a timedelta", + "order": 2, + "content": { + "text": "The result of `end - start` is a `timedelta`, not another datetime. The most exam-useful attribute is usually `.days`.", + "code": "diff = datetime(2024, 1, 1) - datetime(2023, 1, 1)\nprint(diff.days)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "ks-86cd7ede1c", + "snippet-item-kp-manual-datetime-delta", + "snippet-item-manual-timedelta-attrs" + ] + } + ] + }, + { + "id": "datetime-arithmetic-and-comparisons-must_know-datetime-comparisons-behave-like-normal-ordering", + "title": "Datetime comparisons behave like normal ordering", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "You can compare datetimes with `<`, `>`, and `==`. Overlap questions usually combine two comparisons: one start must be before the other end, and one end must be after the other start.", + "source_refs": [ + "manual-datetime-arithmetic", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ], + "pieces": [ + { + "id": "datetime-arithmetic-and-comparisons-must_know-datetime-comparisons-behave-like-normal-ordering-text", + "piece_type": "explanation", + "title": "Datetime comparisons behave like normal ordering", + "order": 1, + "content": { + "text": "You can compare datetimes with `<`, `>`, and `==`. Overlap questions usually combine two comparisons: one start must be before the other end, and one end must be after the other start. self.start < other.end and self.end > other.start" + }, + "selectable": true, + "source_refs": [ + "manual-datetime-arithmetic", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 4, + "snippets": [ + { + "id": "datetime-arithmetic-and-comparisons-exam_patterns-the-classic-trap-strftime-too-early", + "title": "The classic trap: `strftime` too early", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "A wrong option often stores the formatted string in a list and then tries to add another week to that string in the next loop iteration.", + "source_refs": [ + "manual-datetime-arithmetic", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ], + "pieces": [ + { + "id": "dt-strftime-too-early-table", + "piece_type": "reference_table", + "title": "Good pattern vs wrong pattern", + "order": 1, + "content": { + "text": "This is one of the most common datetime distractor patterns.", + "headers": [ + "Pattern", + "Why" + ], + "rows": [ + [ + "keep a datetime in the loop, then format", + "later arithmetic still works" + ], + [ + "format early, then add a timedelta to the string", + "breaks because the value is no longer a datetime" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-datetime-arithmetic", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ] + }, + { + "id": "datetime-arithmetic-and-comparisons-exam_patterns-overlap-logic-is-interval-logic-not-equality-logic", + "title": "Overlap logic is interval logic, not equality logic", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "For event-overlap questions, the winning answer is usually the one that checks interval intersection, not exact matching times.", + "source_refs": [ + "snippet-subtopic-w6-datetime-w6-datetime-core" + ], + "pieces": [ + { + "id": "datetime-arithmetic-and-comparisons-exam_patterns-overlap-logic-is-interval-logic-not-equality-logic-text", + "piece_type": "explanation", + "title": "Overlap logic is interval logic, not equality logic", + "order": 1, + "content": { + "text": "For event-overlap questions, the winning answer is usually the one that checks interval intersection, not exact matching times. Two events overlap when `a.start < b.end and a.end > b.start`." + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ] + }, + { + "id": "datetime-arithmetic-and-comparisons-exam_patterns-constructor-vs-format-confusion-is-a-common-distractor", + "title": "Constructor-vs-format confusion is a common distractor", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "Wrong options often swap constructor order, misuse `strftime` where `strptime` is needed, or try to do datetime math on a string result.", + "source_refs": [ + "manual-datetime-parse-format", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ], + "pieces": [ + { + "id": "dt-constructor-vs-format-table", + "piece_type": "reference_table", + "title": "Constructor vs parse vs format", + "order": 1, + "content": { + "text": "Wrong options often swap these directions.", + "headers": [ + "Task", + "Use" + ], + "rows": [ + [ + "build a datetime from numeric parts", + "datetime(year, month, day, ...)" + ], + [ + "parse text into a datetime", + "datetime.strptime(text, format)" + ], + [ + "turn a datetime into text", + "dt.strftime(format)" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-datetime-parse-format", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ] + }, + { + "id": "datetime-arithmetic-and-comparisons-exam_patterns-build-recurring-schedules-by-advancing-the-datetime-not-the-string", + "title": "Build recurring schedules by advancing the datetime, not the string", + "order": 4, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "For repeated appointments or weekly schedules, keep a datetime in the loop, append the formatted text only at the edge, and advance the datetime with a timedelta each iteration.", + "source_refs": [ + "manual-datetime-arithmetic" + ], + "pieces": [ + { + "id": "dt-recurring-schedule-code", + "piece_type": "code_example", + "title": "Recurring schedule pattern", + "order": 1, + "content": { + "text": "This is the safe loop pattern for weekly date generation questions.", + "code": "current = datetime.strptime('20-05-2024', '%d-%m-%Y')\nrows = []\nfor _ in range(3):\n rows.append(current.strftime('%d-%m-%Y'))\n current += timedelta(days=7)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-datetime-arithmetic" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "datetime-arithmetic-and-comparisons-useful_backup-timedelta-stores-days-seconds-and-microseconds-directly", + "title": "Timedelta stores `days`, `seconds`, and `microseconds` directly", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "This is sometimes useful for eliminating distractors that refer to nonexistent direct attributes like `hours`.", + "source_refs": [ + "snippet-item-manual-timedelta-attrs" + ], + "pieces": [ + { + "id": "datetime-arithmetic-and-comparisons-useful_backup-timedelta-stores-days-seconds-and-microseconds-directly-text", + "piece_type": "explanation", + "title": "Timedelta stores `days`, `seconds`, and `microseconds` directly", + "order": 1, + "content": { + "text": "This is sometimes useful for eliminating distractors that refer to nonexistent direct attributes like `hours`. delta.days, delta.seconds, delta.microseconds" + }, + "selectable": true, + "source_refs": [ + "snippet-item-manual-timedelta-attrs" + ] + } + ] + }, + { + "id": "datetime-arithmetic-and-comparisons-useful_backup-you-can-derive-day-of-year-without-j", + "title": "You can derive day-of-year without `%j`", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Datetime and Time Logic", + "main_topic": "Datetime Arithmetic and Comparisons", + "summary": "Keep this around as a fallback mental model when the format-code route is not obvious.", + "source_refs": [ + "snippet-item-manual-day-of-year", + "snippet-item-kp-manual-datetime-day-of-year" + ], + "pieces": [ + { + "id": "datetime-arithmetic-and-comparisons-useful_backup-you-can-derive-day-of-year-without-j-code", + "piece_type": "code_example", + "title": "You can derive day-of-year without `%j`", + "order": 1, + "content": { + "text": "", + "code": "(dt - datetime(dt.year, 1, 1)).days + 1", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-item-manual-day-of-year", + "snippet-item-kp-manual-datetime-day-of-year" + ] + } + ] + } + ] + } + ] + } + ] + }, + { + "id": "object-oriented-python", + "title": "Object-Oriented Python", + "summary": "Class fundamentals, comparison logic, and inheritance patterns.", + "source_refs": { + "draft_file": "datetime_and_oop.json" + }, + "main_topics": [ + { + "id": "oop-fundamentals", + "title": "OOP Fundamentals", + "summary": "What classes store, what `self` means, how constructor defaults behave, and why method-call syntax creates so many exam traps.", + "parent_topic": "Object-Oriented Python", + "main_week": 4, + "related_weeks": [ + 4 + ], + "topic_order": 21, + "search_text": "OOP Fundamentals What classes store, what `self` means, how constructor defaults behave, and why method-call syntax creates so many exam traps. `self` means the current object Inside instance methods, read and update object state through `self.attribute`. If you assign only to a local variable, that value disappears when the method ends. Method calls pass `self` automatically Use `obj.method(x)`, not `obj.method(obj, x)`. Passing the object again gives one argument too many. Minimal class template you should recognize instantly Many OOP answer choices differ only in whether the class skeleton is written correctly. Know the smallest valid class with an initializer and one method. Defaults in `__init__` make constructor arguments optional A parameter like `mode='land'` may be omitted by the caller, but the instance still gets that value. This matters a lot in exam distractors. Use `None` for fresh per-object collections For list-like constructor arguments, use `None` as the default and create the list inside `__init__` so objects do not accidentally share state. Spot the extra-`self` error immediately If a question shows `my_obj.method(my_obj, value)`, the error is almost always that the instance was passed manually even though Python already supplies it. Distinguish object state from temporary locals An option that writes `name = ...` inside `__init__` or another method without `self.name = ...` usually fails to store the value on the object. Default-argument distractors hide in constructor signatures If the class header already gives a default value, the caller is allowed to omit that argument. Wrong options often pretend the constructor call is missing something required. Trace attribute changes across method calls When the exam creates one object and calls two or three methods on it, keep rewriting the object state after each call instead of trying to reason globally. Class attribute vs instance attribute `self.x` belongs to one object; a class attribute is shared until an instance shadows it. This is useful, but it is not as central as the `self` and method-call traps. OOP reminder table A compact last-minute table for the high-frequency class traps: attributes live on `self`, methods get `self` automatically, and constructor defaults count as provided values.", + "source_refs": {}, + "sections": [ + { + "key": "core_class_basics", + "title": "Core Class Basics", + "description": "The smallest class patterns you should recognize instantly.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "oop-fundamentals-core_class_basics-self-means-the-current-object", + "title": "`self` means the current object", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "Inside instance methods, read and update object state through `self.attribute`. If you assign only to a local variable, that value disappears when the method ends.", + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core", + "snippet-item-manual-self", + "snippet-item-kp-manual-self-attr-d1" + ], + "pieces": [ + { + "id": "oop-fundamentals-core_class_basics-self-means-the-current-object-code", + "piece_type": "code_example", + "title": "`self` means the current object", + "order": 1, + "content": { + "text": "", + "code": "class Flight:\n def set_date(self, date):\n self.date = date", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core", + "snippet-item-manual-self", + "snippet-item-kp-manual-self-attr-d1" + ] + } + ] + }, + { + "id": "oop-fundamentals-core_class_basics-method-calls-pass-self-automatically", + "title": "Method calls pass `self` automatically", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "Use `obj.method(x)`, not `obj.method(obj, x)`. Passing the object again gives one argument too many.", + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-method-call" + ], + "pieces": [ + { + "id": "oop-fundamentals-core_class_basics-method-calls-pass-self-automatically-code", + "piece_type": "code_example", + "title": "Method calls pass `self` automatically", + "order": 1, + "content": { + "text": "", + "code": "obj.set_date(x) # correct\nobj.set_date(obj, x) # too many args", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-method-call" + ] + } + ] + }, + { + "id": "oop-fundamentals-core_class_basics-minimal-class-template-you-should-recognize-instantly", + "title": "Minimal class template you should recognize instantly", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "Many OOP answer choices differ only in whether the class skeleton is written correctly. Know the smallest valid class with an initializer and one method.", + "source_refs": [ + "manual-oop-fundamentals" + ], + "pieces": [ + { + "id": "oop-class-template-code", + "piece_type": "code_example", + "title": "Minimal class template", + "order": 1, + "content": { + "text": "Recognize the skeleton before you reason about the custom logic inside it.", + "code": "class Flight:\n def __init__(self, code, capacity=300):\n self.code = code\n self.capacity = capacity\n\n def seats_left(self):\n return self.capacity", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-oop-fundamentals" + ] + } + ] + } + ] + }, + { + "key": "constructor_defaults", + "title": "Constructor Defaults", + "description": "Constructor signatures, defaults, and per-object state rules.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "oop-fundamentals-constructor_defaults-defaults-in-init-make-constructor-arguments-optional", + "title": "Defaults in `__init__` make constructor arguments optional", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "A parameter like `mode='land'` may be omitted by the caller, but the instance still gets that value. This matters a lot in exam distractors.", + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-init-default", + "snippet-item-kp-manual-init-defaults-d1" + ], + "pieces": [ + { + "id": "oop-fundamentals-constructor_defaults-defaults-in-init-make-constructor-arguments-optional-code", + "piece_type": "code_example", + "title": "Defaults in `__init__` make constructor arguments optional", + "order": 1, + "content": { + "text": "", + "code": "class Vehicle:\n def __init__(self, name, mode='land'):\n self.name = name\n self.mode = mode", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-init-default", + "snippet-item-kp-manual-init-defaults-d1" + ] + } + ] + }, + { + "id": "oop-fundamentals-constructor_defaults-use-none-for-fresh-per-object-collections", + "title": "Use `None` for fresh per-object collections", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "For list-like constructor arguments, use `None` as the default and create the list inside `__init__` so objects do not accidentally share state.", + "source_refs": [ + "snippet-item-kp-manual-init-defaults-d2" + ], + "pieces": [ + { + "id": "oop-fundamentals-constructor_defaults-use-none-for-fresh-per-object-collections-code", + "piece_type": "code_example", + "title": "Use `None` for fresh per-object collections", + "order": 1, + "content": { + "text": "", + "code": "class Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-item-kp-manual-init-defaults-d2" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 4, + "snippets": [ + { + "id": "oop-fundamentals-exam_patterns-spot-the-extra-self-error-immediately", + "title": "Spot the extra-`self` error immediately", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "If a question shows `my_obj.method(my_obj, value)`, the error is almost always that the instance was passed manually even though Python already supplies it.", + "source_refs": [ + "snippet-item-manual-method-call", + "manual-oop-fundamentals" + ], + "pieces": [ + { + "id": "oop-fundamentals-exam_patterns-spot-the-extra-self-error-immediately-code", + "piece_type": "code_example", + "title": "Spot the extra-`self` error immediately", + "order": 1, + "content": { + "text": "", + "code": "my_flight.set_date(my_flight, '29-02-2022')", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-item-manual-method-call", + "manual-oop-fundamentals" + ] + } + ] + }, + { + "id": "oop-fundamentals-exam_patterns-distinguish-object-state-from-temporary-locals", + "title": "Distinguish object state from temporary locals", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "An option that writes `name = ...` inside `__init__` or another method without `self.name = ...` usually fails to store the value on the object.", + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core", + "snippet-item-kp-manual-self-attr-d1" + ], + "pieces": [ + { + "id": "oop-object-state-table", + "piece_type": "reference_table", + "title": "Object state vs local name", + "order": 1, + "content": { + "text": "If the value is meant to survive on the object, store it on `self`.", + "headers": [ + "Code", + "What happens" + ], + "rows": [ + [ + "self.name = vehicle_name", + "stores the value on the object" + ], + [ + "name = vehicle_name", + "creates only a local variable" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core", + "snippet-item-kp-manual-self-attr-d1" + ] + } + ] + }, + { + "id": "oop-fundamentals-exam_patterns-default-argument-distractors-hide-in-constructor-signatures", + "title": "Default-argument distractors hide in constructor signatures", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "If the class header already gives a default value, the caller is allowed to omit that argument. Wrong options often pretend the constructor call is missing something required.", + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-init-default" + ], + "pieces": [ + { + "id": "oop-default-argument-table", + "piece_type": "reference_table", + "title": "Constructor default reminder", + "order": 1, + "content": { + "text": "If the constructor already provides a default, omitting that argument is valid.", + "headers": [ + "Signature shape", + "Caller may do" + ], + "rows": [ + [ + "__init__(self, code, capacity=300)", + "Flight('KLM') or Flight('KLM', 400)" + ], + [ + "__init__(self, code, capacity)", + "must pass both required values" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-init-default" + ] + } + ] + }, + { + "id": "oop-fundamentals-exam_patterns-trace-attribute-changes-across-method-calls", + "title": "Trace attribute changes across method calls", + "order": 4, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "When the exam creates one object and calls two or three methods on it, keep rewriting the object state after each call instead of trying to reason globally.", + "source_refs": [ + "manual-oop-fundamentals", + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core" + ], + "pieces": [ + { + "id": "oop-state-trace-code", + "piece_type": "code_example", + "title": "Tiny state-tracing pattern", + "order": 1, + "content": { + "text": "Write down the attribute after each call. Most mistakes happen when one call mutates the object and the next call reads that updated state.", + "code": "class Book:\n def __init__(self):\n self.reviews = []\n\n def add_review(self, score):\n self.reviews.append(score)\n\nbook = Book()\nbook.add_review(8)\nbook.add_review(6)\nprint(book.reviews) # [8, 6]", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-oop-fundamentals", + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "oop-fundamentals-useful_backup-class-attribute-vs-instance-attribute", + "title": "Class attribute vs instance attribute", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "`self.x` belongs to one object; a class attribute is shared until an instance shadows it. This is useful, but it is not as central as the `self` and method-call traps.", + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core" + ], + "pieces": [ + { + "id": "oop-fundamentals-useful_backup-class-attribute-vs-instance-attribute-code", + "piece_type": "code_example", + "title": "Class attribute vs instance attribute", + "order": 1, + "content": { + "text": "", + "code": "class Counter:\n count = 0", + "output": "" + }, + "selectable": true, + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core" + ] + } + ] + }, + { + "id": "oop-fundamentals-useful_backup-oop-reminder-table", + "title": "OOP reminder table", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Fundamentals", + "summary": "A compact last-minute table for the high-frequency class traps: attributes live on `self`, methods get `self` automatically, and constructor defaults count as provided values.", + "source_refs": [ + "manual-oop-fundamentals" + ], + "pieces": [ + { + "id": "oop-reminder-table", + "piece_type": "reference_table", + "title": "Pattern / Meaning / Trap", + "order": 1, + "content": { + "text": "Compact last-minute table for the class patterns and traps that come up most often.", + "headers": [ + "Pattern", + "Meaning", + "Trap" + ], + "rows": [ + [ + "self.name = value", + "store state on the object", + "plain `name = value` stays local" + ], + [ + "obj.method(x)", + "Python passes `self` automatically", + "do not write `obj.method(obj, x)`" + ], + [ + "mode='land' in __init__", + "caller may omit that argument", + "do not reject valid shorter constructor calls" + ], + [ + "items=None; create list inside __init__", + "fresh list per object", + "mutable defaults can leak state across objects" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-oop-fundamentals" + ] + } + ] + } + ] + } + ] + }, + { + "id": "oop-comparison-logic", + "title": "OOP Comparison Logic", + "summary": "Compare-style methods where one object is only 'better' if multiple conditions are satisfied, and where the correct fallback is often `None`.", + "parent_topic": "Object-Oriented Python", + "main_week": 4, + "related_weeks": [ + 4 + ], + "topic_order": 22, + "search_text": "OOP Comparison Logic Compare-style methods where one object is only 'better' if multiple conditions are satisfied, and where the correct fallback is often `None`. Check both directions explicitly In asymmetric comparison rules, `not self_better` does not mean `other_better`. Compute both conditions and only return a winner when that side truly meets the rule. Use an explicit fallback If neither object wins under the full rule, return `None` (or the stated fallback) instead of guessing that the other object must be better. Reject the fake `elif not avg_better` shortcut A common wrong option says 'if self is not better, return the other object'. That fails whenever neither object satisfies all conditions. Translate the English rule into booleans first Exam wording usually mixes score, review count, and a fallback. Write the rule as named boolean checks before returning anything. Minimal comparison template Keep a tiny three-case table in reserve: self wins, other wins, tie/no clear winner. Comparison checklist table Use a tiny checklist when a class method compares two objects under multiple conditions.", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "oop-comparison-logic-must_know-check-both-directions-explicitly", + "title": "Check both directions explicitly", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Comparison Logic", + "summary": "In asymmetric comparison rules, `not self_better` does not mean `other_better`. Compute both conditions and only return a winner when that side truly meets the rule.", + "source_refs": [ + "manual-oop-comparison", + "snippet-item-kp-manual-oop-compare-d1" + ], + "pieces": [ + { + "id": "oop-comparison-logic-must_know-check-both-directions-explicitly-code", + "piece_type": "code_example", + "title": "Check both directions explicitly", + "order": 1, + "content": { + "text": "", + "code": "self_better = self.avg > other.avg and self.reviews >= other.reviews\nother_better = other.avg > self.avg and other.reviews >= self.reviews", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-oop-comparison", + "snippet-item-kp-manual-oop-compare-d1" + ] + } + ] + }, + { + "id": "oop-comparison-logic-must_know-use-an-explicit-fallback", + "title": "Use an explicit fallback", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Comparison Logic", + "summary": "If neither object wins under the full rule, return `None` (or the stated fallback) instead of guessing that the other object must be better.", + "source_refs": [ + "manual-oop-comparison", + "snippet-item-kp-manual-oop-compare-d1" + ], + "pieces": [ + { + "id": "oop-comparison-logic-must_know-use-an-explicit-fallback-code", + "piece_type": "code_example", + "title": "Use an explicit fallback", + "order": 1, + "content": { + "text": "", + "code": "if self_better:\n return self.title\nif other_better:\n return other.title\nreturn None", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-oop-comparison", + "snippet-item-kp-manual-oop-compare-d1" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "oop-comparison-logic-exam_patterns-reject-the-fake-elif-not-avg-better-shortcut", + "title": "Reject the fake `elif not avg_better` shortcut", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Comparison Logic", + "summary": "A common wrong option says 'if self is not better, return the other object'. That fails whenever neither object satisfies all conditions.", + "source_refs": [ + "manual-oop-comparison" + ], + "pieces": [ + { + "id": "oop-fake-elif-table", + "piece_type": "reference_table", + "title": "Why the shortcut fails", + "order": 1, + "content": { + "text": "Do not let a missing self-win case trick you into assuming the other object must win.", + "headers": [ + "Shortcut", + "Why it is wrong" + ], + "rows": [ + [ + "`elif not avg_better: return other`", + "neither object may satisfy the full rule" + ], + [ + "compute both booleans explicitly", + "you preserve the real tie / no-winner case" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-oop-comparison" + ] + } + ] + }, + { + "id": "oop-comparison-logic-exam_patterns-translate-the-english-rule-into-booleans-first", + "title": "Translate the English rule into booleans first", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Comparison Logic", + "summary": "Exam wording usually mixes score, review count, and a fallback. Write the rule as named boolean checks before returning anything.", + "source_refs": [ + "manual-oop-comparison" + ], + "pieces": [ + { + "id": "oop-comparison-logic-exam_patterns-translate-the-english-rule-into-booleans-first-code", + "piece_type": "code_example", + "title": "Translate the English rule into booleans first", + "order": 1, + "content": { + "text": "", + "code": "avg_better = first.average_score() > second.average_score()\nno_fewer_reviews = first.num_reviews() >= second.num_reviews()", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-oop-comparison" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "oop-comparison-logic-useful_backup-minimal-comparison-template", + "title": "Minimal comparison template", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Comparison Logic", + "summary": "Keep a tiny three-case table in reserve: self wins, other wins, tie/no clear winner.", + "source_refs": [ + "snippet-item-kp-manual-oop-compare-d1" + ], + "pieces": [ + { + "id": "oop-compare-template-table", + "piece_type": "reference_table", + "title": "Three-case comparison template", + "order": 1, + "content": { + "text": "Keep this tiny template in reserve when the method compares two objects under several conditions.", + "headers": [ + "Case", + "Return" + ], + "rows": [ + [ + "self satisfies the full winning rule", + "return the value from self" + ], + [ + "other satisfies the full winning rule", + "return the value from other" + ], + [ + "neither side fully wins", + "return None or the stated fallback" + ] + ] + }, + "selectable": true, + "source_refs": [ + "snippet-item-kp-manual-oop-compare-d1" + ] + } + ] + }, + { + "id": "oop-comparison-logic-useful_backup-comparison-checklist-table", + "title": "Comparison checklist table", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "OOP Comparison Logic", + "summary": "Use a tiny checklist when a class method compares two objects under multiple conditions.", + "source_refs": [ + "manual-oop-comparison" + ], + "pieces": [ + { + "id": "oop-compare-table", + "piece_type": "reference_table", + "title": "Comparison checklist", + "order": 1, + "content": { + "text": "Do not jump straight to `else: return other` unless the rules truly make it exhaustive.", + "headers": [ + "Step", + "Question" + ], + "rows": [ + [ + "1", + "What boolean makes `self` win?" + ], + [ + "2", + "What boolean makes `other` win?" + ], + [ + "3", + "If neither wins, what is the explicit fallback?" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-oop-comparison" + ] + } + ] + } + ] + } + ] + }, + { + "id": "inheritance-and-class-relationships", + "title": "Inheritance and Class Relationships", + "summary": "Parent-child class relationships, `super()`, and what the child keeps from the parent constructor.", + "parent_topic": "Object-Oriented Python", + "main_week": 4, + "related_weeks": [ + 4 + ], + "topic_order": 23, + "search_text": "Inheritance and Class Relationships Parent-child class relationships, `super()`, and what the child keeps from the parent constructor. Subclass syntax and parent initialization Write `class Child(Parent):` to inherit, and call `super().__init__(...)` when the child should keep the parent's setup logic. A child object still counts as the parent type Inheritance does not replace the parent identity; it extends it. A child instance can still be treated as a parent where appropriate. Inheritance quick table A compact checklist for the three cues that matter most in child-class questions. The child should add, not erase, the parent fields Wrong options often forget to call `super().__init__(...)`, which means the inherited attributes are never initialized. Use `super()` when the parent constructor still matters If the parent constructor already handles shared setup, do not copy-paste it into the child unless the question explicitly asks for something else. Three inheritance cues to remember Look for `class Child(Parent):`, `super().__init__(...)`, and `isinstance(child, Parent)` as the quick scan pattern. Child objects inherit parent methods too If `Dog(Animal)` does not override a method, the child object still uses the parent version. Inheritance is not only about shared attributes.", + "source_refs": {}, + "sections": [ + { + "key": "must_know", + "title": "Must Know", + "description": "The fastest, densest references you should reach for first.", + "initial_visible_count": 3, + "snippets": [ + { + "id": "inheritance-and-class-relationships-must_know-subclass-syntax-and-parent-initialization", + "title": "Subclass syntax and parent initialization", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "Inheritance and Class Relationships", + "summary": "Write `class Child(Parent):` to inherit, and call `super().__init__(...)` when the child should keep the parent's setup logic.", + "source_refs": [ + "manual-inheritance" + ], + "pieces": [ + { + "id": "inheritance-and-class-relationships-must_know-subclass-syntax-and-parent-initialization-code", + "piece_type": "code_example", + "title": "Subclass syntax and parent initialization", + "order": 1, + "content": { + "text": "", + "code": "class Dog(Animal):\n def __init__(self, name, breed):\n super().__init__(name)\n self.breed = breed", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-inheritance" + ] + } + ] + }, + { + "id": "inheritance-and-class-relationships-must_know-a-child-object-still-counts-as-the-parent-type", + "title": "A child object still counts as the parent type", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "Inheritance and Class Relationships", + "summary": "Inheritance does not replace the parent identity; it extends it. A child instance can still be treated as a parent where appropriate.", + "source_refs": [ + "manual-inheritance" + ], + "pieces": [ + { + "id": "inheritance-and-class-relationships-must_know-a-child-object-still-counts-as-the-parent-type-code", + "piece_type": "code_example", + "title": "A child object still counts as the parent type", + "order": 1, + "content": { + "text": "", + "code": "isinstance(dog, Animal) # True", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-inheritance" + ] + } + ] + }, + { + "id": "inheritance-and-class-relationships-must_know-inheritance-quick-table", + "title": "Inheritance quick table", + "order": 3, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "Inheritance and Class Relationships", + "summary": "A compact checklist for the three cues that matter most in child-class questions.", + "source_refs": [ + "manual-inheritance" + ], + "pieces": [ + { + "id": "oop-inheritance-table", + "piece_type": "reference_table", + "title": "Inheritance cues", + "order": 1, + "content": { + "text": "These three cues solve a large share of inheritance answer-choice questions.", + "headers": [ + "Cue", + "What it tells you" + ], + "rows": [ + [ + "class Child(Parent):", + "Child inherits parent behavior" + ], + [ + "super().__init__(...)", + "parent initialization still runs" + ], + [ + "child.method()", + "child can use inherited methods unless overridden" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-inheritance" + ] + } + ] + } + ] + }, + { + "key": "exam_patterns", + "title": "Exam Patterns", + "description": "Recurring traps, worked comparisons, and exam-style patterns worth recognizing quickly.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "inheritance-and-class-relationships-exam_patterns-the-child-should-add-not-erase-the-parent-fields", + "title": "The child should add, not erase, the parent fields", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "Inheritance and Class Relationships", + "summary": "Wrong options often forget to call `super().__init__(...)`, which means the inherited attributes are never initialized.", + "source_refs": [ + "manual-inheritance" + ], + "pieces": [ + { + "id": "inheritance-parent-fields-table", + "piece_type": "reference_table", + "title": "Keep the parent setup intact", + "order": 1, + "content": { + "text": "Wrong options often forget the parent initializer, which leaves inherited state incomplete.", + "headers": [ + "Pattern", + "What it means" + ], + "rows": [ + [ + "call `super().__init__(name)`", + "the parent still initializes shared attributes" + ], + [ + "skip the parent initializer entirely", + "shared parent fields may never be created" + ], + [ + "set only the new child field afterward", + "the child adds behavior instead of replacing the parent setup" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-inheritance" + ] + } + ] + }, + { + "id": "inheritance-and-class-relationships-exam_patterns-use-super-when-the-parent-constructor-still-matters", + "title": "Use `super()` when the parent constructor still matters", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "Inheritance and Class Relationships", + "summary": "If the parent constructor already handles shared setup, do not copy-paste it into the child unless the question explicitly asks for something else.", + "source_refs": [ + "manual-inheritance" + ], + "pieces": [ + { + "id": "inheritance-and-class-relationships-exam_patterns-use-super-when-the-parent-constructor-still-matters-code", + "piece_type": "code_example", + "title": "Use `super()` when the parent constructor still matters", + "order": 1, + "content": { + "text": "", + "code": "super().__init__(name)", + "output": "" + }, + "selectable": true, + "source_refs": [ + "manual-inheritance" + ] + } + ] + } + ] + }, + { + "key": "useful_backup", + "title": "Useful Backup", + "description": "Support material to add when a narrower question still leaves a gap.", + "initial_visible_count": 2, + "snippets": [ + { + "id": "inheritance-and-class-relationships-useful_backup-three-inheritance-cues-to-remember", + "title": "Three inheritance cues to remember", + "order": 1, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "Inheritance and Class Relationships", + "summary": "Look for `class Child(Parent):`, `super().__init__(...)`, and `isinstance(child, Parent)` as the quick scan pattern.", + "source_refs": [ + "manual-inheritance" + ], + "pieces": [ + { + "id": "inheritance-and-class-relationships-useful_backup-three-inheritance-cues-to-remember-text", + "piece_type": "explanation", + "title": "Three inheritance cues to remember", + "order": 1, + "content": { + "text": "Look for `class Child(Parent):`, `super().__init__(...)`, and `isinstance(child, Parent)` as the quick scan pattern. These three cues usually identify the correct inheritance answer faster than reading every distractor in full." + }, + "selectable": true, + "source_refs": [ + "manual-inheritance" + ] + } + ] + }, + { + "id": "inheritance-and-class-relationships-useful_backup-child-objects-inherit-parent-methods-too", + "title": "Child objects inherit parent methods too", + "order": 2, + "snippet_type": "general_snippet", + "parent_topic": "Object-Oriented Python", + "main_topic": "Inheritance and Class Relationships", + "summary": "If `Dog(Animal)` does not override a method, the child object still uses the parent version. Inheritance is not only about shared attributes.", + "source_refs": [ + "manual-oop-inheritance" + ], + "pieces": [ + { + "id": "inheritance-method-inheritance-table", + "piece_type": "reference_table", + "title": "What the child automatically gets", + "order": 1, + "content": { + "text": "This helps when answer options confuse inheritance with copy-pasting.", + "headers": [ + "If the parent defines...", + "Then the child has..." + ], + "rows": [ + [ + "attributes created by `super().__init__(...)`", + "the initialized parent state" + ], + [ + "a regular instance method", + "that method too, unless it is overridden" + ], + [ + "a type relationship to the parent", + "`isinstance(child, Parent)` can be True" + ] + ] + }, + "selectable": true, + "source_refs": [ + "manual-oop-inheritance" + ] + } + ] + } + ] + } + ] + } + ] + } + ] +} diff --git a/data/manual_curation_drafts/collections_and_iteration.json b/data/manual_curation_drafts/collections_and_iteration.json new file mode 100644 index 0000000..9d7dc7d --- /dev/null +++ b/data/manual_curation_drafts/collections_and_iteration.json @@ -0,0 +1,870 @@ +{ + "schema_version": "1.0", + "parent_topic_id": "collections-and-iteration", + "parent_topic_title": "Collections and Iteration", + "curation_status": "manual_draft", + "curation_notes": [ + "Built from current data/exam_builder_topics.json and topic_cards.json.", + "This draft keeps only the strongest shipped-ui material for the parent topic and rewrites noisy or unclear source pieces.", + "Weak duplicates, broken examples, and low-yield advanced material were omitted." + ], + "main_topics": [ + { + "id": "lists-and-sets", + "title": "Lists and Sets", + "summary": "Indexing, slicing, list mutation, and the key difference between ordered sequences and unordered unique-value sets.", + "sections": { + "must_know": [ + { + "id": "ls-mk-1", + "title": "Indexing, slicing, and range at a glance", + "kind": "reference_table", + "content": { + "headers": [ + "Pattern", + "Meaning", + "Example result" + ], + "rows": [ + [ + "seq[i]", + "single element at index i", + "['a', 'b', 'c'][1] -> 'b'" + ], + [ + "seq[-1]", + "last element", + "[1, 2, 3][-1] -> 3" + ], + [ + "seq[a:b]", + "start included, stop excluded", + "[1, 2, 3, 4][1:3] -> [2, 3]" + ], + [ + "seq[::2]", + "every second element", + "[1, 2, 3, 4, 5][::2] -> [1, 3, 5]" + ], + [ + "seq[::-1]", + "reversed copy", + "[1, 2, 3][::-1] -> [3, 2, 1]" + ], + [ + "range(start, stop, step)", + "stop is excluded", + "list(range(3, 8, 2)) -> [3, 5, 7]" + ] + ] + }, + "source_snippet_ids": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + }, + { + "id": "ls-mk-2", + "title": "List operations mutate the list", + "kind": "code_example", + "content": { + "text": "Lists are mutable. Read exam code in order and track the updated list after each line.", + "code": "values = [1, 3, 2, 3]\nvalues.append(5) # [1, 3, 2, 3, 5]\nvalues.remove(3) # removes the first 3 only\nprint(values) # [1, 2, 3, 5]" + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + }, + { + "id": "ls-mk-3", + "title": "Ordered sequences vs sets", + "kind": "reference_table", + "content": { + "headers": [ + "Collection", + "Ordered for equality?", + "Duplicates kept?", + "Indexing?" + ], + "rows": [ + [ + "list / tuple / str", + "yes", + "yes", + "yes" + ], + [ + "set", + "no", + "no", + "no" + ], + [ + "dict", + "no for equality", + "keys unique", + "lookup by key, not by position" + ] + ] + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ], + "exam_patterns": [ + { + "id": "ls-ep-1", + "title": "Reverse-and-step slicing trap", + "kind": "code_example", + "content": { + "text": "When a question compares slicing expressions, work left to right. `seq[::2][::-1]` means take every second element first, then reverse that shorter list.", + "code": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nprint(numbers[::2]) # [1, 3, 5, 7, 9]\nprint(numbers[::2][::-1]) # [9, 7, 5, 3, 1]" + }, + "source_snippet_ids": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + }, + { + "id": "ls-ep-2", + "title": "Chunk a list with slicing inside a comprehension", + "kind": "code_example", + "content": { + "text": "A common exam pattern is splitting a list into fixed-size sublists.", + "code": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nchunks = [x[i:i + 3] for i in range(0, len(x), 3)]\nprint(chunks)\n# [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]" + }, + "source_snippet_ids": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + }, + { + "id": "ls-ep-3", + "title": "Check whether all items are unique", + "kind": "code_example", + "content": { + "text": "Turning a sequence into a set removes duplicates, so compare lengths.", + "code": "def all_unique(values):\n return len(values) == len(set(values))" + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ], + "useful_backup": [ + { + "id": "ls-ub-1", + "title": "Find the nth occurrence of a value", + "kind": "code_example", + "content": { + "code": "x = ['A', 'B', 'A', 'C', 'B', 'A', 'B']\nn = 2\ni = -1\nfor _ in range(n):\n i = x.index('B', i + 1)\nprint(i) # 4", + "text": "Use `.index(value, start)` repeatedly when the question asks for the second or third occurrence." + }, + "source_snippet_ids": [ + "snippet-subtopic-w1-sequences-and-access-w1-sequences-and-access-core" + ] + }, + { + "id": "ls-ub-2", + "title": "Set basics worth remembering", + "kind": "reference_table", + "content": { + "headers": [ + "Pattern", + "Reminder" + ], + "rows": [ + [ + "set()", + "creates an empty set" + ], + [ + "{}", + "creates an empty dict, not a set" + ], + [ + "value in my_set", + "membership works, indexing does not" + ], + [ + "my_set.add(x) / update(xs)", + "mutates the set" + ] + ] + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + }, + { + "id": "ls-ub-3", + "title": "Mutating list methods usually return `None`", + "kind": "reference_table", + "content": { + "headers": [ + "Pattern", + "What happens" + ], + "rows": [ + [ + "values.append(5)", + "list changes in place; expression itself returns `None`" + ], + [ + "values.sort()", + "list is reordered in place; expression itself returns `None`" + ], + [ + "sorted(values)", + "returns a new sorted list" + ] + ], + "text": "This trap crosses over with function-return questions, so it is worth keeping explicitly." + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ], + "quick_tables": [ + { + "id": "ls-qt-1", + "title": "List mutation and set reminders", + "kind": "reference_table", + "content": { + "headers": [ + "Pattern", + "Remember" + ], + "rows": [ + [ + "lst.append(x)", + "adds one item at the end" + ], + [ + "lst.sort()", + "sorts in place and returns None" + ], + [ + "lst.append(x)", + "mutates the list; do not assign its return value" + ], + [ + "lst.remove(x)", + "removes the first matching value" + ], + [ + "lst.pop(i)", + "removes and returns an item" + ], + [ + "set()", + "empty set" + ], + [ + "{}", + "empty dict, not a set" + ], + [ + "x in my_set", + "membership works, indexing does not" + ] + ], + "text": "These are the list/set reminders that are easiest to miss in short output questions." + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-lists-and-sets-w2-lists-and-sets-core" + ] + } + ] + } + }, + { + "id": "dictionaries-and-mappings", + "title": "Dictionaries and Mappings", + "summary": "Key-based lookup, membership, iteration, and the most common construction patterns.", + "sections": { + "must_know": [ + { + "id": "dm-mk-1", + "title": "Core dictionary patterns", + "kind": "reference_table", + "content": { + "headers": [ + "Goal", + "Pattern" + ], + "rows": [ + [ + "create", + "{'a': 1, 'b': 2}" + ], + [ + "lookup by key", + "d['a']" + ], + [ + "safe membership check", + "'a' in d" + ], + [ + "safe lookup with fallback", + "d.get('a', 0)" + ], + [ + "iterate keys and values", + "for key, value in d.items():" + ], + [ + "build from pairs", + "dict(zip(keys, values))" + ], + [ + "build with logic", + "{x: len(x) for x in words}" + ] + ] + }, + "source_snippet_ids": [ + "manual-dictionary-patterns" + ] + }, + { + "id": "dm-mk-2", + "title": "What membership and equality actually test", + "kind": "reference_table", + "content": { + "headers": [ + "Expression", + "What it means" + ], + "rows": [ + [ + "'x' in d", + "checks keys only" + ], + [ + "3 in d.values()", + "checks values explicitly" + ], + [ + "{1: 10, 2: 20} == {2: 20, 1: 10}", + "True, insertion order does not matter" + ], + [ + "for key in d", + "same as looping over d.keys()" + ] + ] + }, + "source_snippet_ids": [ + "manual-dictionary-patterns", + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ] + }, + { + "id": "dm-mk-3", + "title": "Minimal code pattern for iteration", + "kind": "code_example", + "content": { + "text": "Most dictionary-loop questions reduce to deciding whether you need keys, values, or both.", + "code": "d = {'a': 3, 'b': 5}\nfor key in d:\n print(key, d[key])\n\nfor key, value in d.items():\n print(key, value)" + }, + "source_snippet_ids": [ + "manual-dictionary-patterns", + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ] + } + ], + "exam_patterns": [ + { + "id": "dm-ep-1", + "title": "Dictionary comprehension and filtering", + "kind": "code_example", + "content": { + "code": "scores = {'Ann': 8, 'Bob': 5, 'Cara': 9}\npassed = {name: score for name, score in scores.items() if score >= 6}", + "text": "If the question asks for a dictionary result, remember that the `key: value` pair comes before `for`." + }, + "source_snippet_ids": [ + "manual-dictionary-patterns", + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + }, + { + "id": "dm-ep-2", + "title": "Transform parallel sequences into a dictionary", + "kind": "code_example", + "content": { + "code": "keys = ['x', 'y', 'z']\nvalues = [1, 2, 3]\nd = dict(zip(keys, values))", + "text": "Use `dict(zip(...))` when the question starts from two separate lists or tuples." + }, + "source_snippet_ids": [ + "manual-dictionary-patterns" + ] + }, + { + "id": "dm-ep-3", + "title": "Count or sum dictionary values", + "kind": "code_example", + "content": { + "code": "sales = {'a': 3, 'b': 5, 'c': 2}\nprint(sum(sales.values())) # 10", + "text": "Many exam questions hide the fact that only the values matter." + }, + "source_snippet_ids": [ + "manual-dictionary-patterns" + ] + } + ], + "useful_backup": [ + { + "id": "dm-ub-1", + "title": "Delete only keys that also exist elsewhere", + "kind": "code_example", + "content": { + "code": "x = {'a': 1, 'b': 2, 'c': 3}\nto_remove = {'c': 3, 'd': 3}\nfor key in to_remove:\n if key in x:\n del x[key]", + "text": "Useful when the exam mixes membership checks with mutation." + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-dictionaries-and-mappings-w2-dictionaries-and-mappings-core" + ] + }, + { + "id": "dm-ub-2", + "title": "Ordered output from a dictionary", + "kind": "code_example", + "content": { + "code": "for key in sorted(d.keys()):\n print(key, d[key])", + "text": "Only sort keys when the question cares about printed order." + }, + "source_snippet_ids": [ + "manual-dictionary-patterns" + ] + } + ], + "quick_tables": [ + { + "id": "dm-qt-1", + "title": "Dictionary methods and iteration quick table", + "kind": "reference_table", + "content": { + "headers": [ + "Pattern", + "Use it for" + ], + "rows": [ + [ + "d[key]", + "direct lookup by key" + ], + [ + "d.get(key, default)", + "safe lookup with fallback" + ], + [ + "key in d", + "membership over keys" + ], + [ + "d.keys() / d.values() / d.items()", + "iterate keys, values, or both" + ], + [ + "dict(zip(keys, values))", + "build from paired iterables" + ] + ], + "text": "This restores the compact dictionary method scan table that helps eliminate distractors quickly." + }, + "source_snippet_ids": [ + "manual-dictionary-patterns" + ] + } + ] + } + }, + { + "id": "loops", + "title": "Loops", + "summary": "Choosing the right loop, using enumerate/zip/items cleanly, and avoiding the standard exam traps.", + "sections": { + "must_know": [ + { + "id": "lp-mk-1", + "title": "Pick the loop shape first", + "kind": "reference_table", + "content": { + "headers": [ + "Need", + "Best pattern" + ], + "rows": [ + [ + "visit every item in an iterable", + "for x in xs:" + ], + [ + "repeat a fixed number of times", + "for _ in range(n):" + ], + [ + "need index and value", + "for i, x in enumerate(xs):" + ], + [ + "walk two iterables together", + "for left, right in zip(a, b):" + ], + [ + "continue while a condition stays true", + "while condition:" + ] + ] + }, + "source_snippet_ids": [ + "manual-iteration-helpers", + "snippet-item-kp-manual-loop-core-d1" + ] + }, + { + "id": "lp-mk-2", + "title": "break, continue, and loop control", + "kind": "reference_table", + "content": { + "headers": [ + "Statement", + "Effect" + ], + "rows": [ + [ + "break", + "exit the loop immediately" + ], + [ + "continue", + "skip the rest of this iteration" + ], + [ + "while items:", + "keep looping while the list is non-empty" + ] + ] + }, + "source_snippet_ids": [ + "snippet-item-manual-break-continue", + "snippet-item-kp-manual-while-truthy" + ] + }, + { + "id": "lp-mk-3", + "title": "Common helper patterns", + "kind": "code_example", + "content": { + "code": "letters = ['a', 'b', 'c']\nfor index, letter in enumerate(letters, start=1):\n print(index, letter)\n\nfor left, right in zip(['x', 'y'], [10, 20]):\n print(left, right)\n\nfor key, value in {'a': 1, 'b': 2}.items():\n print(key, value)", + "text": "These three patterns cover most loop-structure questions." + }, + "source_snippet_ids": [ + "manual-iteration-helpers", + "snippet-subtopic-w2-loops-w2-loops-core" + ] + } + ], + "exam_patterns": [ + { + "id": "lp-ep-1", + "title": "Count matches with sum of booleans", + "kind": "code_example", + "content": { + "code": "nums = [2, 5, 8, 9]\ncount = sum(x % 2 != 0 for x in nums)\nprint(count) # 2", + "text": "In Python, `True` counts as 1 and `False` counts as 0 in numeric contexts." + }, + "source_snippet_ids": [ + "manual-iteration-helpers" + ] + }, + { + "id": "lp-ep-2", + "title": "Translate a slice into an explicit loop", + "kind": "code_example", + "content": { + "code": "alphabet = ['a', 'b', 'c', 'd', 'e', 'f']\nresult = []\nfor i in range(1, len(alphabet), 2):\n result.append(alphabet[i])", + "text": "Useful when the exam asks you to rewrite slicing logic as a loop." + }, + "source_snippet_ids": [ + "snippet-item-manual-loop-translate" + ] + }, + { + "id": "lp-ep-3", + "title": "Nested loops for pairwise results", + "kind": "code_example", + "content": { + "code": "result = {}\nfor first in range(1, 4):\n for second in range(1, 4):\n result[(first, second)] = first + second", + "text": "If every item must be combined with every other item, expect a nested loop." + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-loops-w2-loops-core" + ] + } + ], + "useful_backup": [ + { + "id": "lp-ub-1", + "title": "Loop variable intentionally unused", + "kind": "code_example", + "content": { + "code": "for _ in range(3):\n print('repeat')", + "text": "Use `_` when only the number of repetitions matters." + }, + "source_snippet_ids": [ + "snippet-subtopic-w2-loops-w2-loops-core" + ] + }, + { + "id": "lp-ub-2", + "title": "Iterator basics", + "kind": "code_example", + "content": { + "code": "it = iter([1, 2])\nprint(next(it))\nprint(next(it))", + "text": "Low priority for the shipped UI, but helpful if a question mentions `iter()` or `next()` directly." + }, + "source_snippet_ids": [ + "snippet-subtopic-w6-generators-and-iterators-w6-generators-and-iterators-core" + ] + }, + { + "id": "lp-ub-3", + "title": "range(start, stop, step) still excludes stop", + "kind": "reference_table", + "content": { + "headers": [ + "Code", + "Result", + "Why" + ], + "rows": [ + [ + "list(range(6))", + "[0, 1, 2, 3, 4, 5]", + "starts at 0 by default" + ], + [ + "list(range(3, 6))", + "[3, 4, 5]", + "stop value 6 is excluded" + ], + [ + "list(range(3, 9, 2))", + "[3, 5, 7]", + "step controls the jump size" + ] + ], + "text": "Off-by-one mistakes in `range(...)` still decide a surprising number of loop questions." + }, + "source_snippet_ids": [ + "manual-iteration-helpers" + ] + } + ], + "quick_tables": [ + { + "id": "lp-qt-1", + "title": "Loop helper cheat table", + "kind": "reference_table", + "content": { + "headers": [ + "Need", + "Pattern" + ], + "rows": [ + [ + "index + value", + "for i, x in enumerate(xs):" + ], + [ + "pair two iterables", + "for left, right in zip(a, b):" + ], + [ + "repeat n times", + "for _ in range(n):" + ], + [ + "skip current iteration", + "continue" + ], + [ + "exit loop entirely", + "break" + ] + ], + "text": "These are the loop helpers most worth keeping nearby during the exam." + }, + "source_snippet_ids": [ + "manual-iteration-helpers", + "snippet-item-manual-break-continue" + ] + } + ] + } + }, + { + "id": "comprehensions", + "title": "Comprehensions", + "summary": "Recognize list/set/dict comprehension syntax quickly and separate filtering from value transformation.", + "sections": { + "must_know": [ + { + "id": "cp-mk-1", + "title": "Comprehension templates", + "kind": "reference_table", + "content": { + "headers": [ + "Type", + "Template", + "Example" + ], + "rows": [ + [ + "list", + "[expr for x in xs]", + "[x * 2 for x in xs]" + ], + [ + "list with filter", + "[expr for x in xs if cond]", + "[x for x in xs if x > 0]" + ], + [ + "list with if/else", + "[a if cond else b for x in xs]", + "[x if x > 0 else 0 for x in xs]" + ], + [ + "set", + "{expr for x in xs}", + "{len(name) for name in names}" + ], + [ + "dict", + "{key: value for x in xs}", + "{name: len(name) for name in names}" + ] + ] + }, + "source_snippet_ids": [ + "manual-comprehension-syntax" + ] + }, + { + "id": "cp-mk-2", + "title": "Filter vs transform placement rule", + "kind": "code_example", + "content": { + "code": "positives = [value for value in nums if value > 0]\nflipped = [letter.lower() if letter.isupper() else letter.upper() for letter in letters]", + "text": "Trailing `if` removes items. Inline `a if cond else b` changes the output value while keeping one output per input." + }, + "source_snippet_ids": [ + "manual-comprehension-syntax", + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + }, + { + "id": "cp-mk-3", + "title": "String output still needs join", + "kind": "code_example", + "content": { + "code": "result = ''.join([char * 2 if char.lower() in 'aeiou' else char for char in 'Python'])", + "text": "Python has list comprehensions, not native string comprehensions. Build characters first, then `''.join(...)` them." + }, + "source_snippet_ids": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ], + "exam_patterns": [ + { + "id": "cp-ep-1", + "title": "Dictionary comprehension with items()", + "kind": "code_example", + "content": { + "code": "d = {'a': 1, 'b': 2}\nfiltered = {k: v for k, v in d.items() if v > 1}", + "text": "This is the standard exam pattern for filtering or transforming dictionaries." + }, + "source_snippet_ids": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + }, + { + "id": "cp-ep-2", + "title": "Set comprehension means uniqueness", + "kind": "code_example", + "content": { + "code": "values = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}\nprint(values)", + "text": "Use a set comprehension when duplicates should collapse automatically." + }, + "source_snippet_ids": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + }, + { + "id": "cp-ep-3", + "title": "enumerate inside a comprehension", + "kind": "code_example", + "content": { + "code": "res = [val // (i + 6) for i, val in enumerate([46, 48])]", + "text": "Keep this pattern in reserve when the expression depends on both index and value." + }, + "source_snippet_ids": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + } + ], + "useful_backup": [ + { + "id": "cp-ub-1", + "title": "Nested comprehension example", + "kind": "code_example", + "content": { + "code": "result = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}", + "text": "Useful if the exam includes nested structures, but too advanced to surface as core shipped material." + }, + "source_snippet_ids": [ + "snippet-subtopic-w6-comprehensions-w6-comprehensions-core" + ] + }, + { + "id": "cp-ub-2", + "title": "The expression must produce a value, not a side effect", + "kind": "reference_table", + "content": { + "headers": [ + "Wrong instinct", + "Why it fails", + "Better pattern" + ], + "rows": [ + [ + "[result.append(x) for x in xs]", + "append returns `None`, so the comprehension collects `None` values", + "[x for x in xs] or build the list in a normal loop" + ], + [ + "[print(x) for x in xs]", + "prints as a side effect instead of building useful values", + "use a normal loop for printing" + ], + [ + "{d.update({k: v}) for k, v in pairs}", + "update mutates and returns `None`", + "{k: v for k, v in pairs}" + ] + ], + "text": "Use comprehensions to build values. If the real goal is mutation or printing, a normal loop is clearer and usually correct." + }, + "source_snippet_ids": [ + "manual-comprehension-syntax" + ] + } + ] + } + } + ] +} diff --git a/data/manual_curation_drafts/datetime_and_oop.json b/data/manual_curation_drafts/datetime_and_oop.json new file mode 100644 index 0000000..b07375e --- /dev/null +++ b/data/manual_curation_drafts/datetime_and_oop.json @@ -0,0 +1,1083 @@ +[ + { + "id": "datetime-and-time-logic", + "title": "Datetime and Time Logic", + "main_topics": [ + { + "id": "datetime-parsing-and-formatting", + "title": "Datetime Parsing and Formatting", + "summary": "Parsing date text into datetime objects, formatting datetime objects back into strings, and remembering the small set of format codes that actually shows up in exams.", + "curation_notes": [ + "Merged the duplicate strptime-vs-strftime snippets, format-code tables, and object-vs-string reminders into a tighter core.", + "Kept the code patterns that let a zero-knowledge student decode exam options quickly.", + "Dropped noisy now()/timestamp examples from the core because they are weak for the shipped UI unless the question is explicitly about them." + ], + "sections": { + "must_know": [ + { + "title": "Parse first, format last", + "summary": "`datetime.strptime(text, format)` turns text into a datetime object; `dt.strftime(format)` turns a datetime object into text. Do math and attribute access while it is still a datetime object.", + "example": "from datetime import datetime\nstart = datetime.strptime('20-05-2024', '%d-%m-%Y')\nprint(start.strftime('%Y/%m/%d'))", + "source_refs": [ + "manual-datetime-parse-format", + "snippet-item-manual-strftime-vs-strptime", + "kp-manual-datetime-objects-vs-strings" + ], + "pieces": [ + { + "id": "dt-parse-vs-format-table", + "piece_type": "reference_table", + "title": "Parse vs format", + "content": { + "headers": [ + "Call", + "Input", + "Output" + ], + "rows": [ + [ + "datetime.strptime(text, fmt)", + "string + format", + "datetime object" + ], + [ + "dt.strftime(fmt)", + "datetime object + format", + "string" + ] + ], + "text": "Do arithmetic and attribute access while the value is still a datetime object." + }, + "source_refs": [ + "manual-datetime-parse-format", + "snippet-item-manual-strftime-vs-strptime", + "kp-manual-datetime-objects-vs-strings" + ] + }, + { + "id": "dt-parse-vs-format-code", + "piece_type": "code_example", + "title": "Parse first, format last", + "content": { + "text": "`datetime.strptime(text, format)` turns text into a datetime object; `dt.strftime(format)` turns a datetime object into text. Do math and attribute access while it is still a datetime object.", + "code": "from datetime import datetime\nstart = datetime.strptime('20-05-2024', '%d-%m-%Y')\nprint(start.strftime('%Y/%m/%d'))" + }, + "source_refs": [ + "manual-datetime-parse-format", + "snippet-item-manual-strftime-vs-strptime", + "kp-manual-datetime-objects-vs-strings" + ] + } + ] + }, + { + "title": "Know the exam format codes by sight", + "summary": "The recurring codes are `%Y` year, `%y` 2-digit year, `%m` month, `%d` day, `%H` hour, `%M` minute, `%S` second, and `%j` day-of-year. Constructor order is year, month, day.", + "example": "datetime.strptime('2023/1/10', '%Y/%m/%d')\ndt.strftime('%d-%m-%Y')\n# 10-01-2023", + "source_refs": [ + "snippet-item-kp-manual-datetime-format-codes-d1", + "snippet-item-kp-manual-datetime-format-codes", + "ks-169cc25be1", + "ks-755c23c4be" + ], + "pieces": [ + { + "id": "dt-format-codes-table", + "piece_type": "reference_table", + "title": "Format codes you should recognize instantly", + "content": { + "headers": [ + "Code", + "Meaning", + "Example" + ], + "rows": [ + [ + "%Y", + "4-digit year", + "2024" + ], + [ + "%y", + "2-digit year", + "24" + ], + [ + "%m", + "month number", + "03" + ], + [ + "%d", + "day of month", + "09" + ], + [ + "%H", + "hour (24h)", + "17" + ], + [ + "%M", + "minute", + "05" + ], + [ + "%S", + "second", + "42" + ], + [ + "%j", + "day of year", + "060" + ] + ], + "text": "Constructor order is year, month, day. Formatting codes are read literally in exam answer options." + }, + "source_refs": [ + "snippet-item-kp-manual-datetime-format-codes-d1", + "snippet-item-kp-manual-datetime-format-codes", + "ks-169cc25be1", + "ks-755c23c4be" + ] + }, + { + "id": "dt-format-codes-code", + "piece_type": "code_example", + "title": "Parse then format with the same mental map", + "content": { + "text": "The recurring codes are `%Y` year, `%y` 2-digit year, `%m` month, `%d` day, `%H` hour, `%M` minute, `%S` second, and `%j` day-of-year. Constructor order is year, month, day.", + "code": "dt = datetime.strptime('2023/1/10', '%Y/%m/%d')\nprint(dt.strftime('%d-%m-%Y')) # 10-01-2023" + }, + "source_refs": [ + "snippet-item-kp-manual-datetime-format-codes-d1", + "snippet-item-kp-manual-datetime-format-codes", + "ks-169cc25be1", + "ks-755c23c4be" + ] + } + ] + }, + { + "title": "Object vs string mental model", + "summary": "A parsed datetime supports `.year`, `.month`, comparisons, and arithmetic. A formatted string does not. If an option formats too early, it usually breaks the later arithmetic step.", + "example": "dt = datetime.strptime('01-06-2023 09:30', '%d-%m-%Y %H:%M')\ntext = dt.strftime('%d-%m-%Y %H:%M')\n# dt + timedelta(minutes=20) works\n# text + timedelta(minutes=20) does not", + "source_refs": [ + "snippet-item-kp-manual-datetime-objects-vs-strings-d1", + "snippet-item-kp-manual-datetime-objects-vs-strings" + ] + } + ], + "exam_patterns": [ + { + "title": "Decode the date format from the sample string", + "summary": "If the question shows both the input string and the format template, match separators and positions directly. This is usually enough to identify the month/day/year meaning without extra theory.", + "pieces": [ + { + "id": "dt-decode-format-table", + "piece_type": "reference_table", + "title": "Read the sample string literally", + "content": { + "headers": [ + "Sample", + "Format", + "Meaning" + ], + "rows": [ + [ + "03/02/2013", + "%m/%d/%Y", + "month 3, day 2, year 2013" + ], + [ + "03-02-2013", + "%d-%m-%Y", + "day 3, month 2, year 2013" + ] + ], + "text": "Match separators and positions directly; that is usually enough to eliminate the wrong options." + }, + "source_refs": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ], + "source_refs": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + }, + { + "title": "Day-of-year questions use one of two routes", + "summary": "Either use `%j` when formatting, or compute `(dt - datetime(dt.year, 1, 1)).days + 1`. Exam distractors often forget the `+ 1` or return a timedelta instead of an integer.", + "example": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "source_refs": [ + "snippet-item-manual-day-of-year", + "snippet-item-kp-manual-datetime-day-of-year", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + }, + { + "title": "DataFrame date-column questions still reduce to parse/format rules", + "summary": "When a question builds a `Date` column from day, month, and year pieces, the winning option usually constructs a datetime in year-month-day order and then formats it with `strftime`.", + "example": "datetime(y, m, d).strftime('%d-%m-%Y')", + "source_refs": [ + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ], + "useful_backup": [ + { + "title": "`replace()` returns a new datetime", + "summary": "Datetime objects are immutable. `replace(...)` gives you a modified copy; it does not change the original object in place.", + "example": "d = datetime.now()\nd2 = d.replace(year=2026)", + "source_refs": [ + "ks-662456da41", + "snippet-item-kp-manual-datetime-replace" + ] + }, + { + "title": "`now()`, `timestamp()`, and ISO helpers", + "summary": "These are fine references to have nearby, but they are backup material here because they are lower-frequency than parse/format and arithmetic traps.", + "example": "datetime.now().timestamp()\nd.isoformat()\nd.isocalendar()", + "source_refs": [ + "ks-e643ee5e77", + "snippet-item-kp-manual-datetime-now", + "snippet-item-kp-manual-datetime-iso" + ] + }, + { + "title": "Weekday, month, and year attributes are direct lookups", + "summary": "Once you have a datetime object, use attributes like `.year`, `.month`, `.day`, and `.weekday()` directly instead of re-formatting the date string.", + "pieces": [ + { + "id": "dt-attributes-table", + "piece_type": "reference_table", + "title": "Direct datetime attributes", + "content": { + "headers": [ + "Attribute / call", + "Returns" + ], + "rows": [ + [ + "dt.year", + "integer year" + ], + [ + "dt.month", + "integer month" + ], + [ + "dt.day", + "integer day" + ], + [ + "dt.weekday()", + "0=Monday ... 6=Sunday" + ] + ], + "text": "Use attributes on the datetime object itself; do not format to text first unless the question wants text output." + }, + "source_refs": [ + "manual-datetime-parse-format" + ] + } + ], + "source_refs": [ + "manual-datetime-parse-format" + ] + } + ] + } + }, + { + "id": "datetime-arithmetic-and-comparisons", + "title": "Datetime Arithmetic and Comparisons", + "summary": "Timedelta arithmetic, overlap/comparison logic, and the specific traps that show up when an option turns a datetime into text too early.", + "curation_notes": [ + "Collapsed the arithmetic snippets into one clear 'do math before formatting' rule plus a small support layer for comparisons and overlap checks.", + "Kept timedelta attributes as backup rather than core because `.days` matters far more often than the full attribute list." + ], + "sections": { + "must_know": [ + { + "title": "Do arithmetic before formatting", + "summary": "Add or subtract `timedelta(...)` while the value is a datetime object. Only call `strftime(...)` after the arithmetic is finished.", + "example": "from datetime import datetime, timedelta\nstart = datetime.strptime('2024-05-20', '%Y-%m-%d')\nnext_week = start + timedelta(days=7)\nprint(next_week.strftime('%Y-%m-%d'))", + "source_refs": [ + "manual-datetime-arithmetic", + "kp-manual-datetime-objects-vs-strings" + ] + }, + { + "title": "Subtracting datetimes gives a timedelta", + "summary": "The result of `end - start` is a `timedelta`, not another datetime. The most exam-useful attribute is usually `.days`.", + "example": "diff = datetime(2024, 1, 1) - datetime(2023, 1, 1)\nprint(diff.days)", + "source_refs": [ + "ks-86cd7ede1c", + "snippet-item-kp-manual-datetime-delta", + "snippet-item-manual-timedelta-attrs" + ], + "pieces": [ + { + "id": "dt-delta-table", + "piece_type": "reference_table", + "title": "Datetime subtraction and timedelta facts", + "content": { + "headers": [ + "Expression", + "Result" + ], + "rows": [ + [ + "end - start", + "timedelta" + ], + [ + "start + timedelta(days=7)", + "datetime" + ], + [ + "diff.days", + "whole-day count" + ], + [ + "timedelta(hours=2, minutes=30)", + "2.5 hours" + ] + ], + "text": "The most exam-useful timedelta attribute is usually `.days`." + }, + "source_refs": [ + "ks-86cd7ede1c", + "snippet-item-kp-manual-datetime-delta", + "snippet-item-manual-timedelta-attrs" + ] + }, + { + "id": "dt-delta-code", + "piece_type": "code_example", + "title": "Subtracting datetimes gives a timedelta", + "content": { + "text": "The result of `end - start` is a `timedelta`, not another datetime. The most exam-useful attribute is usually `.days`.", + "code": "diff = datetime(2024, 1, 1) - datetime(2023, 1, 1)\nprint(diff.days)" + }, + "source_refs": [ + "ks-86cd7ede1c", + "snippet-item-kp-manual-datetime-delta", + "snippet-item-manual-timedelta-attrs" + ] + } + ] + }, + { + "title": "Datetime comparisons behave like normal ordering", + "summary": "You can compare datetimes with `<`, `>`, and `==`. Overlap questions usually combine two comparisons: one start must be before the other end, and one end must be after the other start.", + "example": "self.start < other.end and self.end > other.start", + "source_refs": [ + "manual-datetime-arithmetic", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ], + "exam_patterns": [ + { + "title": "The classic trap: `strftime` too early", + "summary": "A wrong option often stores the formatted string in a list and then tries to add another week to that string in the next loop iteration.", + "pieces": [ + { + "id": "dt-strftime-too-early-table", + "piece_type": "reference_table", + "title": "Good pattern vs wrong pattern", + "content": { + "headers": [ + "Pattern", + "Why" + ], + "rows": [ + [ + "keep a datetime in the loop, then format", + "later arithmetic still works" + ], + [ + "format early, then add a timedelta to the string", + "breaks because the value is no longer a datetime" + ] + ], + "text": "This is one of the most common datetime distractor patterns." + }, + "source_refs": [ + "manual-datetime-arithmetic", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ], + "source_refs": [ + "manual-datetime-arithmetic", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + }, + { + "title": "Overlap logic is interval logic, not equality logic", + "summary": "For event-overlap questions, the winning answer is usually the one that checks interval intersection, not exact matching times.", + "example": "Two events overlap when `a.start < b.end and a.end > b.start`.", + "source_refs": [ + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + }, + { + "title": "Constructor-vs-format confusion is a common distractor", + "summary": "Wrong options often swap constructor order, misuse `strftime` where `strptime` is needed, or try to do datetime math on a string result.", + "pieces": [ + { + "id": "dt-constructor-vs-format-table", + "piece_type": "reference_table", + "title": "Constructor vs parse vs format", + "content": { + "headers": [ + "Task", + "Use" + ], + "rows": [ + [ + "build a datetime from numeric parts", + "datetime(year, month, day, ...)" + ], + [ + "parse text into a datetime", + "datetime.strptime(text, format)" + ], + [ + "turn a datetime into text", + "dt.strftime(format)" + ] + ], + "text": "Wrong options often swap these directions." + }, + "source_refs": [ + "manual-datetime-parse-format", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + } + ], + "source_refs": [ + "manual-datetime-parse-format", + "snippet-subtopic-w6-datetime-w6-datetime-core" + ] + }, + { + "title": "Build recurring schedules by advancing the datetime, not the string", + "summary": "For repeated appointments or weekly schedules, keep a datetime in the loop, append the formatted text only at the edge, and advance the datetime with a timedelta each iteration.", + "pieces": [ + { + "id": "dt-recurring-schedule-code", + "piece_type": "code_example", + "title": "Recurring schedule pattern", + "content": { + "text": "This is the safe loop pattern for weekly date generation questions.", + "code": "current = datetime.strptime('20-05-2024', '%d-%m-%Y')\nrows = []\nfor _ in range(3):\n rows.append(current.strftime('%d-%m-%Y'))\n current += timedelta(days=7)" + }, + "source_refs": [ + "manual-datetime-arithmetic" + ] + } + ], + "source_refs": [ + "manual-datetime-arithmetic" + ] + } + ], + "useful_backup": [ + { + "title": "Timedelta stores `days`, `seconds`, and `microseconds` directly", + "summary": "This is sometimes useful for eliminating distractors that refer to nonexistent direct attributes like `hours`.", + "example": "delta.days, delta.seconds, delta.microseconds", + "source_refs": [ + "snippet-item-manual-timedelta-attrs" + ] + }, + { + "title": "You can derive day-of-year without `%j`", + "summary": "Keep this around as a fallback mental model when the format-code route is not obvious.", + "example": "(dt - datetime(dt.year, 1, 1)).days + 1", + "source_refs": [ + "snippet-item-manual-day-of-year", + "snippet-item-kp-manual-datetime-day-of-year" + ] + } + ] + } + } + ] + }, + { + "id": "object-oriented-python", + "title": "Object-Oriented Python", + "main_topics": [ + { + "id": "oop-fundamentals", + "title": "OOP Fundamentals", + "summary": "What classes store, what `self` means, how constructor defaults behave, and why method-call syntax creates so many exam traps.", + "curation_notes": [ + "Merged the overlapping `self`, method-call, attribute, and default-argument snippets into one practical exam-facing core.", + "Kept the mutable-default constructor fix because it is stronger than the extra duplicate default-arg examples.", + "Omitted weaker near-duplicates that only rephrased the same `self` rule without adding exam value." + ], + "sections": { + "core_class_basics": { + "title": "Core Class Basics", + "description": "The smallest class patterns you should recognize instantly.", + "snippets": [ + { + "title": "`self` means the current object", + "summary": "Inside instance methods, read and update object state through `self.attribute`. If you assign only to a local variable, that value disappears when the method ends.", + "example": "class Flight:\n def set_date(self, date):\n self.date = date", + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core", + "snippet-item-manual-self", + "snippet-item-kp-manual-self-attr-d1" + ] + }, + { + "title": "Method calls pass `self` automatically", + "summary": "Use `obj.method(x)`, not `obj.method(obj, x)`. Passing the object again gives one argument too many.", + "example": "obj.set_date(x) # correct\nobj.set_date(obj, x) # too many args", + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-method-call" + ] + }, + { + "title": "Minimal class template you should recognize instantly", + "summary": "Many OOP answer choices differ only in whether the class skeleton is written correctly. Know the smallest valid class with an initializer and one method.", + "pieces": [ + { + "id": "oop-class-template-code", + "piece_type": "code_example", + "title": "Minimal class template", + "content": { + "text": "Recognize the skeleton before you reason about the custom logic inside it.", + "code": "class Flight:\n def __init__(self, code, capacity=300):\n self.code = code\n self.capacity = capacity\n\n def seats_left(self):\n return self.capacity" + }, + "source_refs": [ + "manual-oop-fundamentals" + ] + } + ], + "source_refs": [ + "manual-oop-fundamentals" + ] + } + ] + }, + "constructor_defaults": { + "title": "Constructor Defaults", + "description": "Constructor signatures, defaults, and per-object state rules.", + "snippets": [ + { + "title": "Defaults in `__init__` make constructor arguments optional", + "summary": "A parameter like `mode='land'` may be omitted by the caller, but the instance still gets that value. This matters a lot in exam distractors.", + "example": "class Vehicle:\n def __init__(self, name, mode='land'):\n self.name = name\n self.mode = mode", + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-init-default", + "snippet-item-kp-manual-init-defaults-d1" + ] + }, + { + "title": "Use `None` for fresh per-object collections", + "summary": "For list-like constructor arguments, use `None` as the default and create the list inside `__init__` so objects do not accidentally share state.", + "example": "class Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores", + "source_refs": [ + "snippet-item-kp-manual-init-defaults-d2" + ] + } + ] + }, + "exam_patterns": [ + { + "title": "Spot the extra-`self` error immediately", + "summary": "If a question shows `my_obj.method(my_obj, value)`, the error is almost always that the instance was passed manually even though Python already supplies it.", + "example": "my_flight.set_date(my_flight, '29-02-2022')", + "source_refs": [ + "snippet-item-manual-method-call", + "manual-oop-fundamentals" + ] + }, + { + "title": "Distinguish object state from temporary locals", + "summary": "An option that writes `name = ...` inside `__init__` or another method without `self.name = ...` usually fails to store the value on the object.", + "pieces": [ + { + "id": "oop-object-state-table", + "piece_type": "reference_table", + "title": "Object state vs local name", + "content": { + "headers": [ + "Code", + "What happens" + ], + "rows": [ + [ + "self.name = vehicle_name", + "stores the value on the object" + ], + [ + "name = vehicle_name", + "creates only a local variable" + ] + ], + "text": "If the value is meant to survive on the object, store it on `self`." + }, + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core", + "snippet-item-kp-manual-self-attr-d1" + ] + } + ], + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core", + "snippet-item-kp-manual-self-attr-d1" + ] + }, + { + "title": "Default-argument distractors hide in constructor signatures", + "summary": "If the class header already gives a default value, the caller is allowed to omit that argument. Wrong options often pretend the constructor call is missing something required.", + "pieces": [ + { + "id": "oop-default-argument-table", + "piece_type": "reference_table", + "title": "Constructor default reminder", + "content": { + "headers": [ + "Signature shape", + "Caller may do" + ], + "rows": [ + [ + "__init__(self, code, capacity=300)", + "Flight('KLM') or Flight('KLM', 400)" + ], + [ + "__init__(self, code, capacity)", + "must pass both required values" + ] + ], + "text": "If the constructor already provides a default, omitting that argument is valid." + }, + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-init-default" + ] + } + ], + "source_refs": [ + "manual-oop-fundamentals", + "snippet-item-manual-init-default" + ] + }, + { + "title": "Trace attribute changes across method calls", + "summary": "When the exam creates one object and calls two or three methods on it, keep rewriting the object state after each call instead of trying to reason globally.", + "pieces": [ + { + "id": "oop-state-trace-code", + "piece_type": "code_example", + "title": "Tiny state-tracing pattern", + "content": { + "text": "Write down the attribute after each call. Most mistakes happen when one call mutates the object and the next call reads that updated state.", + "code": "class Book:\n def __init__(self):\n self.reviews = []\n\n def add_review(self, score):\n self.reviews.append(score)\n\nbook = Book()\nbook.add_review(8)\nbook.add_review(6)\nprint(book.reviews) # [8, 6]" + }, + "source_refs": [ + "manual-oop-fundamentals", + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core" + ] + } + ], + "source_refs": [ + "manual-oop-fundamentals", + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core" + ] + } + ], + "useful_backup": [ + { + "title": "Class attribute vs instance attribute", + "summary": "`self.x` belongs to one object; a class attribute is shared until an instance shadows it. This is useful, but it is not as central as the `self` and method-call traps.", + "example": "class Counter:\n count = 0", + "source_refs": [ + "snippet-subtopic-w4-oop-fundamentals-w4-oop-fundamentals-core" + ] + }, + { + "title": "OOP reminder table", + "summary": "A compact last-minute table for the high-frequency class traps: attributes live on `self`, methods get `self` automatically, and constructor defaults count as provided values.", + "pieces": [ + { + "id": "oop-reminder-table", + "piece_type": "reference_table", + "title": "Pattern / Meaning / Trap", + "content": { + "headers": [ + "Pattern", + "Meaning", + "Trap" + ], + "rows": [ + [ + "self.name = value", + "store state on the object", + "plain `name = value` stays local" + ], + [ + "obj.method(x)", + "Python passes `self` automatically", + "do not write `obj.method(obj, x)`" + ], + [ + "mode='land' in __init__", + "caller may omit that argument", + "do not reject valid shorter constructor calls" + ], + [ + "items=None; create list inside __init__", + "fresh list per object", + "mutable defaults can leak state across objects" + ] + ], + "text": "Compact last-minute table for the class patterns and traps that come up most often." + }, + "source_refs": [ + "manual-oop-fundamentals" + ] + } + ], + "source_refs": [ + "manual-oop-fundamentals" + ] + } + ] + } + }, + { + "id": "oop-comparison-logic", + "title": "OOP Comparison Logic", + "summary": "Compare-style methods where one object is only 'better' if multiple conditions are satisfied, and where the correct fallback is often `None`.", + "curation_notes": [ + "This topic is already thin and useful, so the draft keeps it compact instead of over-expanding it with generic comparison material.", + "Merged the reusable compare template and the fallback logic into one crisp rule set." + ], + "sections": { + "must_know": [ + { + "title": "Check both directions explicitly", + "summary": "In asymmetric comparison rules, `not self_better` does not mean `other_better`. Compute both conditions and only return a winner when that side truly meets the rule.", + "example": "self_better = self.avg > other.avg and self.reviews >= other.reviews\nother_better = other.avg > self.avg and other.reviews >= self.reviews", + "source_refs": [ + "manual-oop-comparison", + "snippet-item-kp-manual-oop-compare-d1" + ] + }, + { + "title": "Use an explicit fallback", + "summary": "If neither object wins under the full rule, return `None` (or the stated fallback) instead of guessing that the other object must be better.", + "example": "if self_better:\n return self.title\nif other_better:\n return other.title\nreturn None", + "source_refs": [ + "manual-oop-comparison", + "snippet-item-kp-manual-oop-compare-d1" + ] + } + ], + "exam_patterns": [ + { + "title": "Reject the fake `elif not avg_better` shortcut", + "summary": "A common wrong option says 'if self is not better, return the other object'. That fails whenever neither object satisfies all conditions.", + "pieces": [ + { + "id": "oop-fake-elif-table", + "piece_type": "reference_table", + "title": "Why the shortcut fails", + "content": { + "headers": [ + "Shortcut", + "Why it is wrong" + ], + "rows": [ + [ + "`elif not avg_better: return other`", + "neither object may satisfy the full rule" + ], + [ + "compute both booleans explicitly", + "you preserve the real tie / no-winner case" + ] + ], + "text": "Do not let a missing self-win case trick you into assuming the other object must win." + }, + "source_refs": [ + "manual-oop-comparison" + ] + } + ], + "source_refs": [ + "manual-oop-comparison" + ] + }, + { + "title": "Translate the English rule into booleans first", + "summary": "Exam wording usually mixes score, review count, and a fallback. Write the rule as named boolean checks before returning anything.", + "example": "avg_better = first.average_score() > second.average_score()\nno_fewer_reviews = first.num_reviews() >= second.num_reviews()", + "source_refs": [ + "manual-oop-comparison" + ] + } + ], + "useful_backup": [ + { + "title": "Minimal comparison template", + "summary": "Keep a tiny three-case table in reserve: self wins, other wins, tie/no clear winner.", + "source_refs": [ + "snippet-item-kp-manual-oop-compare-d1" + ], + "pieces": [ + { + "id": "oop-compare-template-table", + "piece_type": "reference_table", + "title": "Three-case comparison template", + "content": { + "headers": [ + "Case", + "Return" + ], + "rows": [ + [ + "self satisfies the full winning rule", + "return the value from self" + ], + [ + "other satisfies the full winning rule", + "return the value from other" + ], + [ + "neither side fully wins", + "return None or the stated fallback" + ] + ], + "text": "Keep this tiny template in reserve when the method compares two objects under several conditions." + }, + "source_refs": [ + "snippet-item-kp-manual-oop-compare-d1" + ] + } + ] + }, + { + "title": "Comparison checklist table", + "summary": "Use a tiny checklist when a class method compares two objects under multiple conditions.", + "pieces": [ + { + "id": "oop-compare-table", + "piece_type": "reference_table", + "title": "Comparison checklist", + "content": { + "headers": [ + "Step", + "Question" + ], + "rows": [ + [ + "1", + "What boolean makes `self` win?" + ], + [ + "2", + "What boolean makes `other` win?" + ], + [ + "3", + "If neither wins, what is the explicit fallback?" + ] + ], + "text": "Do not jump straight to `else: return other` unless the rules truly make it exhaustive." + }, + "source_refs": [ + "manual-oop-comparison" + ] + } + ], + "source_refs": [ + "manual-oop-comparison" + ] + } + ] + } + }, + { + "id": "inheritance-and-class-relationships", + "title": "Inheritance and Class Relationships", + "summary": "Parent-child class relationships, `super()`, and what the child keeps from the parent constructor.", + "curation_notes": [ + "Kept this topic lean because the current repo data is already fairly clean here.", + "Focused on the patterns most likely to help in shipped UI: inheritance syntax, parent initialization, and the 'child is still a parent' mental model." + ], + "sections": { + "must_know": [ + { + "title": "Subclass syntax and parent initialization", + "summary": "Write `class Child(Parent):` to inherit, and call `super().__init__(...)` when the child should keep the parent's setup logic.", + "example": "class Dog(Animal):\n def __init__(self, name, breed):\n super().__init__(name)\n self.breed = breed", + "source_refs": [ + "manual-inheritance" + ] + }, + { + "title": "A child object still counts as the parent type", + "summary": "Inheritance does not replace the parent identity; it extends it. A child instance can still be treated as a parent where appropriate.", + "example": "isinstance(dog, Animal) # True", + "source_refs": [ + "manual-inheritance" + ] + }, + { + "title": "Inheritance quick table", + "summary": "A compact checklist for the three cues that matter most in child-class questions.", + "pieces": [ + { + "id": "oop-inheritance-table", + "piece_type": "reference_table", + "title": "Inheritance cues", + "content": { + "headers": [ + "Cue", + "What it tells you" + ], + "rows": [ + [ + "class Child(Parent):", + "Child inherits parent behavior" + ], + [ + "super().__init__(...)", + "parent initialization still runs" + ], + [ + "child.method()", + "child can use inherited methods unless overridden" + ] + ], + "text": "These three cues solve a large share of inheritance answer-choice questions." + }, + "source_refs": [ + "manual-inheritance" + ] + } + ], + "source_refs": [ + "manual-inheritance" + ] + } + ], + "exam_patterns": [ + { + "title": "The child should add, not erase, the parent fields", + "summary": "Wrong options often forget to call `super().__init__(...)`, which means the inherited attributes are never initialized.", + "source_refs": [ + "manual-inheritance" + ], + "pieces": [ + { + "id": "inheritance-parent-fields-table", + "piece_type": "reference_table", + "title": "Keep the parent setup intact", + "content": { + "headers": [ + "Pattern", + "What it means" + ], + "rows": [ + [ + "call `super().__init__(name)`", + "the parent still initializes shared attributes" + ], + [ + "skip the parent initializer entirely", + "shared parent fields may never be created" + ], + [ + "set only the new child field afterward", + "the child adds behavior instead of replacing the parent setup" + ] + ], + "text": "Wrong options often forget the parent initializer, which leaves inherited state incomplete." + }, + "source_refs": [ + "manual-inheritance" + ] + } + ] + }, + { + "title": "Use `super()` when the parent constructor still matters", + "summary": "If the parent constructor already handles shared setup, do not copy-paste it into the child unless the question explicitly asks for something else.", + "example": "super().__init__(name)", + "source_refs": [ + "manual-inheritance" + ] + } + ], + "useful_backup": [ + { + "title": "Three inheritance cues to remember", + "summary": "Look for `class Child(Parent):`, `super().__init__(...)`, and `isinstance(child, Parent)` as the quick scan pattern.", + "example": "These three cues usually identify the correct inheritance answer faster than reading every distractor in full.", + "source_refs": [ + "manual-inheritance" + ] + }, + { + "title": "Child objects inherit parent methods too", + "summary": "If `Dog(Animal)` does not override a method, the child object still uses the parent version. Inheritance is not only about shared attributes.", + "pieces": [ + { + "id": "inheritance-method-inheritance-table", + "piece_type": "reference_table", + "title": "What the child automatically gets", + "content": { + "headers": [ + "If the parent defines...", + "Then the child has..." + ], + "rows": [ + [ + "attributes created by `super().__init__(...)`", + "the initialized parent state" + ], + [ + "a regular instance method", + "that method too, unless it is overridden" + ], + [ + "a type relationship to the parent", + "`isinstance(child, Parent)` can be True" + ] + ], + "text": "This helps when answer options confuse inheritance with copy-pasting." + }, + "source_refs": [ + "manual-oop-inheritance" + ] + } + ], + "source_refs": [ + "manual-oop-inheritance" + ] + } + ] + } + } + ] + } +] diff --git a/data/manual_curation_drafts/functions_and_program_flow.json b/data/manual_curation_drafts/functions_and_program_flow.json new file mode 100644 index 0000000..e381325 --- /dev/null +++ b/data/manual_curation_drafts/functions_and_program_flow.json @@ -0,0 +1,540 @@ +{ + "id": "functions-and-program-flow", + "title": "Functions and Program Flow", + "summary": "Manual curation draft for the shipped UI. This parent topic keeps only compact, exam-useful material for function syntax, imports, flexible arguments, scope/return behavior, and lambda-style patterns.", + "source_inputs": [ + "data/exam_builder_topics.json", + "topic_cards.json", + "data/vision_exam_pipeline/review_packets/round1.json", + "data/vision_exam_pipeline/analytics/round1.json" + ], + "main_topics": [ + { + "id": "functions-and-imports", + "title": "Functions and Imports", + "summary": "Defining a function, calling it correctly, and knowing which names an import statement actually creates.", + "sections": { + "must_know": [ + { + "id": "fi-call-return-basics", + "title": "Define with `def`, call with `()`, and return the value you want the caller to use", + "format": "code_example", + "content": { + "text": "Use `def name(params):` to define a function. Call it with `name(...)`. `print(...)` only displays a value; `return` sends it back to the caller.", + "code": "def add(a, b):\n return a + b\n\nresult = add(2, 3)\nprint(result) # 5" + }, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-2", + "topic_cards.json#w3-defining-and-calling-functions:kp-1", + "topic_cards.json#w3-defining-and-calling-functions:kp-3" + ] + }, + { + "id": "fi-import-binding-reference", + "title": "Import name-binding reference", + "format": "reference_table", + "content": { + "text": "The important exam question is not what module was imported, but which name is actually available afterwards.", + "table": { + "headers": [ + "Statement", + "Use this name later", + "Not this" + ], + "rows": [ + [ + "import math", + "math.pi", + "pi" + ], + [ + "import math as m", + "m.pi", + "math.pi" + ], + [ + "from math import pi", + "pi", + "math.pi" + ], + [ + "from math import pi as constant", + "constant", + "pi" + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-1", + "topic_cards.json#w1-functions-and-imports:ai-example-1", + "topic_cards.json#w1-functions-and-imports:ai-example-2", + "topic_cards.json#w1-functions-and-imports:ai-example-5" + ] + } + ], + "exam_patterns": [ + { + "id": "fi-alias-trap", + "title": "Alias trap: the alias replaces the old module name in your code", + "format": "reference_table", + "content": { + "table": { + "headers": [ + "Code", + "Works?", + "Why" + ], + "rows": [ + [ + "import math as constants\\nconstants.pi", + "Yes", + "You must use the alias you created." + ], + [ + "import math as constants\\nmath.pi", + "No", + "The bare name `math` was never bound." + ], + [ + "from math import pi as constant\\nconstant * r ** 2", + "Yes", + "The imported name is `constant`." + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:exam-intro_python_sample_final_24_25-24-w2-conditions" + ] + }, + { + "id": "fi-branch-return-shape", + "title": "In multi-branch function questions, check both the logic and the exact return shape", + "format": "concept", + "content": { + "text": "A function can fail an exam question even when the math is almost right. Check three things: every branch assigns the needed values, the function returns the requested object shape, and helper code is used as a value rather than left as a function object." + }, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:exam-midterm_2023-12-w1-functions-and-imports" + ] + } + ], + "useful_backup": [ + { + "id": "fi-builtins-mini-reference", + "title": "Useful built-ins that often appear inside small helper functions", + "format": "reference_table", + "content": { + "table": { + "headers": [ + "Call", + "Purpose", + "Typical result" + ], + "rows": [ + [ + "int('123')", + "string to integer", + "123" + ], + [ + "float('123')", + "string to float", + "123.0" + ], + [ + "str(123.0)", + "number to string", + "'123.0'" + ], + [ + "round(x, 2)", + "round for display/checking", + "2 decimals" + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w1-functions-and-imports:kp-1-d2" + ] + } + ] + } + }, + { + "id": "flexible-arguments-and-kwargs", + "title": "Flexible Arguments and kwargs", + "summary": "Reading function headers with defaults, `*args`, and `**kwargs`, and tracing what a call actually passes in.", + "sections": { + "must_know": [ + { + "id": "fa-signature-reference", + "title": "Read the function header from left to right", + "format": "reference_table", + "content": { + "table": { + "headers": [ + "Header piece", + "Meaning" + ], + "rows": [ + [ + "x", + "required positional parameter" + ], + [ + "y=0", + "optional parameter with a default" + ], + [ + "*args", + "extra positional arguments as a tuple" + ], + [ + "**kwargs", + "extra keyword arguments as a dict" + ], + [ + "return a, b", + "one tuple comes back" + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w3-arguments:kp-1", + "topic_cards.json#w3-arguments:kp-2", + "topic_cards.json#w3-arguments:kp-manual-args-kwargs-return" + ] + }, + { + "id": "fa-defaults-and-none-fix", + "title": "Defaults are evaluated once; never use a mutable object as the default", + "format": "code_example", + "content": { + "text": "A list or dict default persists across calls. Use `None` and create a fresh container inside the function.", + "code": "def collect(item, items=None):\n if items is None:\n items = []\n items.append(item)\n return items" + }, + "source_refs": [ + "topic_cards.json#w3-arguments:kp-3", + "topic_cards.json#w3-arguments:ai-example-6" + ] + } + ], + "exam_patterns": [ + { + "id": "fa-keyword-order-pattern", + "title": "Keyword arguments can appear in any order as long as the names match", + "format": "code_example", + "content": { + "code": "def calc(first, second, third):\n return first + 2 * second + 3 * third\n\nprint(calc(third=4, second=2, first=3)) # 19", + "text": "The call order does not matter here because the argument names decide where each value goes." + }, + "source_refs": [ + "topic_cards.json#w3-arguments:kp-2-d1", + "topic_cards.json#w3-arguments:ai-example-3" + ] + }, + { + "id": "fa-mixed-flexible-header-pattern", + "title": "Mixed header pattern: required values first, then extras, then named options", + "format": "code_example", + "content": { + "code": "def multiply(*args, factor=2):\n total = 1\n for num in args:\n total *= num\n return total * factor", + "text": "Common exam move: `*args` collects the numbers, while a named option like `factor=` stays readable in the call." + }, + "source_refs": [ + "topic_cards.json#w3-arguments:exam-midterm_2024-14-w3-arguments" + ] + } + ], + "useful_backup": [ + { + "id": "fa-tuple-return-unpack", + "title": "Flexible header plus tuple return", + "format": "code_example", + "content": { + "code": "def collect(first, *args, scale=1, **kwargs):\n return first * scale, args, kwargs\n\nresult, extras, options = collect(2, 3, 4, scale=10, unit='cm')\nprint(result) # 20\nprint(extras) # (3, 4)\nprint(options) # {'unit': 'cm'}", + "text": "This is compact but high-value because it combines the most common header features in one traceable example." + }, + "source_refs": [ + "topic_cards.json#w3-arguments:manual-args-kwargs-return" + ] + } + ] + } + }, + { + "id": "scope-and-return-behavior", + "title": "Scope and Return Behavior", + "summary": "What names exist where, how values escape a function, and why `None` appears so often in function questions.", + "sections": { + "must_know": [ + { + "id": "sr-scope-rules", + "title": "Scope rules to check before tracing any function", + "format": "reference_table", + "content": { + "table": { + "headers": [ + "Rule", + "Consequence" + ], + "rows": [ + [ + "Parameter names and assigned names inside a function are local by default.", + "They cannot be used outside that function." + ], + [ + "If a function assigns to a name anywhere, Python treats that name as local throughout that function.", + "You can get `UnboundLocalError` even before the assignment line." + ], + [ + "`global x` rebinds the global name `x`.", + "Use it only when you really want to change the global." + ], + [ + "`nonlocal x` rebinds the nearest enclosing local name `x`.", + "Use it in nested functions when you want the inner function to update the outer function's variable." + ], + [ + "If the caller needs a value later, return it and assign the result.", + "Do not expect local names to survive the call." + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w3-scope:kp-manual-scope-local", + "topic_cards.json#w3-scope:kp-manual-scope-unbound", + "topic_cards.json#w3-scope:kp-manual-scope-global", + "topic_cards.json#w3-scope:kp-manual-scope-return-outside" + ] + }, + { + "id": "sr-return-vs-print", + "title": "`return` sends a value back; `print` only shows it", + "format": "concept", + "content": { + "text": "A function that prints a value but does not return it still returns `None`. In exam traces, always ask: what comes back to the caller?" + }, + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-1", + "topic_cards.json#w3-return-behavior:ai-example-5", + "topic_cards.json#w3-return-behavior:ai-example-6" + ] + }, + { + "id": "sr-none-traps", + "title": "Common `None` traps", + "format": "reference_table", + "content": { + "table": { + "headers": [ + "Code shape", + "What comes back" + ], + "rows": [ + [ + "function reaches end with no `return`", + "None" + ], + [ + "branch that never hits a `return`", + "None" + ], + [ + "l1.sort() / l1.append(x)", + "None" + ], + [ + "s.upper()", + "new string" + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-2", + "topic_cards.json#w3-return-behavior:kp-manual-mutating-methods-none", + "topic_cards.json#w3-defining-and-calling-functions:kp-2" + ] + } + ], + "exam_patterns": [ + { + "id": "sr-local-name-outside-function", + "title": "Local-name error: computing a value inside the function does not make it global", + "format": "code_example", + "content": { + "code": "def power(num, factor):\n result = num ** factor\n return result\n\nprint(result)", + "text": "`result` is local to `power`, so `print(result)` outside the function fails." + }, + "source_refs": [ + "topic_cards.json#w3-scope:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "topic_cards.json#w3-scope:exam-Resit 22/23-2-w3-scope" + ] + }, + { + "id": "sr-unboundlocal-pattern", + "title": "Self-reference after assignment makes the name local and uninitialized", + "format": "code_example", + "content": { + "code": "b = 1\n\ndef main(a):\n b = b\n return a\n\nprint(main(1))", + "text": "Because `b` is assigned inside `main`, Python treats it as local from the start of the function. The right-hand `b` has no value yet." + }, + "source_refs": [ + "topic_cards.json#w3-scope:manual-scope-unbound" + ] + } + ], + "useful_backup": [ + { + "id": "sr-one-element-tuple-pass", + "title": "Small syntax traps worth keeping in backup", + "format": "reference_table", + "content": { + "table": { + "headers": [ + "Pattern", + "Meaning" + ], + "rows": [ + [ + "(1)", + "just the integer 1" + ], + [ + "(1,)", + "one-element tuple" + ], + [ + "pass", + "placeholder statement; does nothing" + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w3-return-behavior:kp-3", + "topic_cards.json#w3-return-behavior:kp-4" + ] + } + ] + } + }, + { + "id": "lambda-and-higher-order-patterns", + "title": "Lambda and Higher-Order Patterns", + "summary": "Small inline functions, `map(...)`, `sorted(..., key=...)`, and the few recurring higher-order patterns that show up in exams.", + "sections": { + "must_know": [ + { + "id": "lh-lambda-map-sorted-reference", + "title": "Compact lambda / map / sorted reference", + "format": "reference_table", + "content": { + "table": { + "headers": [ + "Pattern", + "Use" + ], + "rows": [ + [ + "lambda x: x * 2", + "small inline function for one value" + ], + [ + "list(map(f, seq))", + "apply `f` to every element and materialize the result" + ], + [ + "sorted(seq, key=f)", + "sort by a computed comparison key" + ], + [ + "sorted(seq, key=f, reverse=True)", + "same key, descending order" + ] + ] + } + }, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:kp-2", + "topic_cards.json#w3-higher-order-patterns:kp-3", + "topic_cards.json#w3-higher-order-patterns:ai-example-8" + ] + }, + { + "id": "lh-map-is-lazy", + "title": "`map(...)` is lazy; wrap it in `list(...)` when the question expects visible values", + "format": "code_example", + "content": { + "code": "nums = [1, 2, 3]\nprint(list(map(lambda x: x * 2, nums))) # [2, 4, 6]", + "text": "A common wrong option prints the raw `map` object instead of materializing the mapped values." + }, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:ai-example-3", + "topic_cards.json#w3-higher-order-patterns:kp-3" + ] + } + ], + "exam_patterns": [ + { + "id": "lh-sort-key-pattern", + "title": "Sort by a property, not by the raw value", + "format": "code_example", + "content": { + "code": "def sort_list(x):\n return sorted(x, key=lambda num: abs(num), reverse=True)", + "text": "This exact exam pattern checks whether you know that `key=` computes the comparison value and `reverse=True` flips the final order." + }, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2023-11-w3-higher-order-patterns" + ] + }, + { + "id": "lh-function-list-pattern", + "title": "Apply several functions to the same input", + "format": "code_example", + "content": { + "code": "funcs = [square, cube]\nfor i in my_list:\n results = map(lambda f: f(i), funcs)\n print(list(results))", + "text": "Read `lambda f: f(i)` as: take one function from `funcs`, call it on the current number `i`, then collect the outputs." + }, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2023-13-w3-higher-order-patterns" + ] + }, + { + "id": "lh-whole-list-vs-one-element", + "title": "Check whether the function expects one number or the whole list", + "format": "concept", + "content": { + "text": "Many distractors fail because they pass the entire list into a function that was written for a single element. `map(f, [1,2,3])` calls `f(1)`, then `f(2)`, then `f(3)`; `f([1,2,3])` is a completely different call." + }, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:exam-trial_midterm-17-w3-higher-order-patterns", + "topic_cards.json#w3-higher-order-patterns:exam-midterm_2024-19-w3-higher-order-patterns" + ] + } + ], + "useful_backup": [ + { + "id": "lh-function-factory", + "title": "Nested function / factory pattern", + "format": "code_example", + "content": { + "code": "def function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\n\nadd4 = function_factory(4)\nprint(add4(3)) # 7", + "text": "Lower-frequency than `lambda` and `map`, but still worth keeping as backup because it tests the idea that functions are objects and can be returned." + }, + "source_refs": [ + "topic_cards.json#w3-higher-order-patterns:kp-1", + "topic_cards.json#w3-higher-order-patterns:ai-example-1" + ] + } + ] + } + } + ] +} diff --git a/data/manual_curation_drafts/pandas_data_work.json b/data/manual_curation_drafts/pandas_data_work.json new file mode 100644 index 0000000..148cd29 --- /dev/null +++ b/data/manual_curation_drafts/pandas_data_work.json @@ -0,0 +1,509 @@ +{ + "parent_topic_id": "pandas-data-work", + "parent_topic_title": "Pandas Data Work", + "manual_curation_version": 1, + "curated_on": "2026-03-24", + "curation_notes": [ + "This draft aggressively merges repetitive week-5 pandas snippets into exam-usable parent-topic summaries.", + "Weak one-line duplicates and low-signal micro-snippets were omitted unless they added a concrete exam distinction." + ], + "main_topics": [ + { + "id": "pandas-core-structures", + "title": "Pandas Core Structures", + "sections": { + "must_know": [ + { + "title": "Know the three base objects cold: `Series`, `DataFrame`, and the default index", + "summary": "A `Series` is one labeled column of data. A `DataFrame` is a 2D table built most often from a dict of equal-length lists. If you do not supply an index, pandas gives `0, 1, 2, ...` automatically.", + "example": "import pandas as pd\ns = pd.Series([153, 160, 150], name='Length')\ndf = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})", + "why_kept": "This is foundational and cleaner than shipping several separate low-value constructor snippets.", + "source_basis": [ + "manual-pandas-df", + "manual-pandas-import", + "ks-052ed25923", + "ks-9a5d2c05fb" + ], + "pieces": [ + { + "id": "pandas-core-objects-table", + "piece_type": "reference_table", + "title": "Series, DataFrame, and default index", + "content": { + "headers": [ + "Object", + "Think of it as", + "Default index if omitted" + ], + "rows": [ + [ + "Series", + "one labeled column", + "0, 1, 2, ..." + ], + [ + "DataFrame", + "2D table of aligned columns", + "0, 1, 2, ..." + ] + ], + "text": "A DataFrame is most often built from a dict of equal-length lists." + }, + "source_refs": [ + "manual-pandas-df", + "manual-pandas-import", + "ks-052ed25923", + "ks-9a5d2c05fb" + ] + }, + { + "id": "pandas-core-objects-code", + "piece_type": "code_example", + "title": "Know the three base objects cold: `Series`, `DataFrame`, and the default index", + "content": { + "text": "A `Series` is one labeled column of data. A `DataFrame` is a 2D table built most often from a dict of equal-length lists. If you do not supply an index, pandas gives `0, 1, 2, ...` automatically.", + "code": "import pandas as pd\ns = pd.Series([153, 160, 150], name='Length')\ndf = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})" + }, + "source_refs": [ + "manual-pandas-df", + "manual-pandas-import", + "ks-052ed25923", + "ks-9a5d2c05fb" + ] + } + ] + }, + { + "title": "Shape rule that keeps appearing on exams: `df['A']` vs `df[['A']]`", + "summary": "`df['A']` returns a `Series` (1D). `df[['A']]` returns a one-column `DataFrame` (2D). Use the list form whenever the question explicitly wants a DataFrame back.", + "example": "df['A'] # Series\ndf[['A']] # one-column DataFrame\ndf[['A', 'B']] # two-column DataFrame", + "why_kept": "This is one of the highest-payoff pandas distinctions and should be stated once, clearly, instead of repeated in fragmented forms.", + "source_basis": [ + "manual-series-vs-dataframe", + "kp-manual-series-vs-df-d1" + ], + "pieces": [ + { + "id": "pandas-shape-rules-table", + "piece_type": "reference_table", + "title": "Selection shape rules", + "content": { + "headers": [ + "Form", + "Returns", + "Why it matters" + ], + "rows": [ + [ + "df['A']", + "Series", + "one column, 1D" + ], + [ + "df[['A']]", + "DataFrame", + "one-column table, stays 2D" + ], + [ + "df[['A', 'B']]", + "DataFrame", + "multi-column subset" + ] + ], + "text": "When the prompt explicitly wants a DataFrame back, keep the selection 2D." + }, + "source_refs": [ + "manual-series-vs-dataframe", + "kp-manual-series-vs-df-d1" + ] + }, + { + "id": "pandas-shape-rules-code", + "piece_type": "code_example", + "title": "Shape rule that keeps appearing on exams: `df['A']` vs `df[['A']]`", + "content": { + "text": "`df['A']` returns a `Series` (1D). `df[['A']]` returns a one-column `DataFrame` (2D). Use the list form whenever the question explicitly wants a DataFrame back.", + "code": "df['A'] # Series\ndf[['A']] # one-column DataFrame\ndf[['A', 'B']] # two-column DataFrame" + }, + "source_refs": [ + "manual-series-vs-dataframe", + "kp-manual-series-vs-df-d1" + ] + } + ] + }, + { + "title": "Use direct column arithmetic for derived columns before reaching for `map` or `apply`", + "summary": "If the task is plain elementwise column math, write the vectorized expression directly. Do not wrap simple column addition or subtraction in `map(...)` or row-wise `apply(...)` unless the question truly needs custom per-value or per-row logic.", + "example": "df['C'] = df['A'] + df['B']\ndf['D'] = df['A'] - df['B']", + "why_kept": "This merges the strongest Week 5 pattern with the most common mistake pattern.", + "source_basis": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet-item-kp-5-d2" + ] + } + ], + "exam_patterns": [ + { + "title": "Creating a new column from existing columns", + "summary": "Exam questions repeatedly test whether you understand that new columns are assigned by column name and filled with vectorized Series results.", + "pattern": "df['C'] = df['A'] + df['B']\n# or\ndf.loc[:, 'C'] = df.loc[:, 'A'] + df.loc[:, 'B']", + "watch_out": [ + "Do not write `df['A' + 'B']`.", + "Do not use a row label like `df.loc['C']` when the goal is a new column." + ], + "source_basis": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "title": "The classic trap: `map` is not a shortcut for vectorized arithmetic", + "summary": "`Series.map(...)` expects a function, dict, or mapping-like Series. If the whole expression already works elementwise, use the vectorized form directly.", + "pattern": "(s - s.mean())**2", + "anti_pattern": "s.map((s - s.mean())**2)", + "source_basis": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "kp-5" + ] + }, + { + "title": "Constructor and selection cheat table", + "summary": "A compact table for the constructors and access forms that look similar but return different shapes.", + "pieces": [ + { + "id": "pandas-construct-select-table", + "piece_type": "reference_table", + "title": "Constructor and selection cheat table", + "content": { + "headers": [ + "Pattern", + "Use it for" + ], + "rows": [ + [ + "pd.Series([10, 20, 30])", + "one labeled column" + ], + [ + "pd.DataFrame({'A': [1, 2], 'B': [3, 4]})", + "2D table" + ], + [ + "df['A']", + "one column as Series" + ], + [ + "df[['A']]", + "one-column DataFrame" + ] + ], + "text": "This gives you the constructor and shape rules in one glance." + }, + "source_refs": [ + "manual-pandas-df", + "manual-series-vs-dataframe" + ] + } + ], + "source_refs": [ + "manual-pandas-df", + "manual-series-vs-dataframe" + ] + } + ], + "useful_backup": [ + { + "title": "Index alignment can silently create `NaN` values", + "summary": "When pandas combines Series or DataFrames, it aligns by index labels. If indices do not match, the result can fill with `NaN` instead of doing row-by-row arithmetic by position.", + "example": "df2 += pd.DataFrame({'A': [2, 5, 6], 'B': [3, 4, 7]}, index=[4, 5, 6])", + "why_backup": "Useful and exam-relevant, but less core than constructors, shape, and direct column arithmetic.", + "source_basis": [ + "cs-b069af91f4" + ] + }, + { + "title": "DatetimeIndex matters only when the index actually stores dates", + "summary": "If the DataFrame index is a `DatetimeIndex`, rows can be filtered using date attributes like `.month`. This is worth keeping as a backup, not a headline rule.", + "example": "df.loc[[r for r in df.index if r.month == 4]]", + "why_backup": "Legitimate pattern, but too specialized to sit in shipped must-know content.", + "source_basis": [ + "ks-75cf35c8b4" + ] + } + ] + }, + "dropped_or_merged": [ + "Merged repeated constructor/alias snippets into one clean basics rule.", + "Dropped noisy dataframe-mutation examples that are harder to memorize than they are worth for the UI." + ] + }, + { + "id": "inspecting-and-selecting-data", + "title": "Inspecting and Selecting Data", + "sections": { + "must_know": [ + { + "title": "Selection rule in one sentence: plain `df[...]` is not for two axes", + "summary": "Use plain `df[...]` for column selection or a boolean row mask. The moment both a row selector and a column selector appear, switch to `.loc[row_sel, col_sel]` or `.iloc[row_sel, col_sel]`.", + "example": "df['A']\ndf[df['A'] > 0]\ndf.loc[2:4, ['B']]\ndf.iloc[1:4, [1]]\n# not: df[2, 'B']", + "why_kept": "This is the clearest repeated weakness and should be shipped as a flagship snippet.", + "source_basis": [ + "manual-pandas-selection", + "kp-manual-pandas-two-axis-d1", + "kp-6" + ] + }, + { + "title": "Know the `loc` vs `iloc` slicing difference exactly", + "summary": "`.loc` is label-based and includes the stop label in a slice. `.iloc` is integer-position based and excludes the stop position, like normal Python slicing.", + "example": "df.loc['First':'Third', ['Name', 'Weight']]\ndf.iloc[0:2, 0:1]", + "why_kept": "Students confuse these constantly, and the distinction directly affects exam answers.", + "source_basis": [ + "manual-pandas-selection", + "ks-57ff66f9f1", + "ks-dfc064979d" + ] + }, + { + "title": "Selection shape is part of the answer, not a side detail", + "summary": "A scalar selector often collapses the result to a `Series`; wrapping labels in a list usually keeps a `DataFrame`. When the prompt says 'return a DataFrame', preserve 2D shape intentionally.", + "example": "df.loc[2] # Series\ndf.loc[[2]] # DataFrame\ndf.loc[df.index % 2 == 0, ['B']] # DataFrame, not Series", + "why_kept": "Several exam questions turn entirely on result shape.", + "source_basis": [ + "ks-99fe849762", + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "title": "Valid vs invalid two-axis selection", + "summary": "This is the table that helps you reject impossible pandas indexing forms immediately.", + "pieces": [ + { + "id": "pandas-valid-invalid-table", + "piece_type": "reference_table", + "title": "Valid vs invalid selection forms", + "content": { + "headers": [ + "Code", + "Valid?", + "Meaning" + ], + "rows": [ + [ + "df.loc[2:4, ['B']]", + "yes", + "label-based rows + named columns" + ], + [ + "df.iloc[1:4, [1]]", + "yes", + "position-based rows + columns" + ], + [ + "df.loc[df['A'] > 0, ['B', 'C']]", + "yes", + "boolean mask rows + named columns" + ], + [ + "df[df['A'] > 0]", + "yes", + "row filtering only" + ], + [ + "df[2, 'B']", + "no", + "plain df[...] is not for two axes" + ] + ], + "text": "Switch to `.loc[...]` or `.iloc[...]` as soon as you need both rows and columns." + }, + "source_refs": [ + "manual-pandas-selection", + "kp-manual-pandas-two-axis-d1" + ] + } + ], + "source_refs": [ + "manual-pandas-selection", + "kp-manual-pandas-two-axis-d1" + ] + } + ], + "exam_patterns": [ + { + "title": "Select one column for rows that satisfy a row rule", + "summary": "Build the row condition first, then choose the target column(s). If the task wants a DataFrame, keep the column selector as a list.", + "pattern": "df.loc[df.index % 2 == 0, ['B']]", + "watch_out": [ + "`df.loc[2::2, 'B']` may return a Series instead of the required DataFrame.", + "`df[2, 4, 6, 'B']` is invalid." + ], + "source_basis": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "title": "Boolean mask plus explicit columns is the safest exam default", + "summary": "When the prompt mixes filtering and selection, `df.loc[mask, columns]` is usually the clearest and least error-prone form.", + "pattern": "mask = df['A'] > 0\nresult = df.loc[mask, ['B', 'C']]", + "source_basis": [ + "manual-pandas-selection", + "ai-example-8", + "kp-5" + ] + } + ], + "useful_backup": [ + { + "title": "Quick inspection helpers", + "summary": "Use `.head(n)` and `.tail(n)` to inspect rows and `.describe()` for summary statistics. These are useful, but they should stay backup material rather than taking premium UI space.", + "example": "df.head(3)\ndf.tail(2)\ndf.describe()", + "why_backup": "Helpful for orientation, but rarely the decisive concept in multiple-choice exam questions.", + "source_basis": [ + "ai-example-1", + "ks-0114a2cff0" + ] + } + ] + }, + "dropped_or_merged": [ + "Collapsed many near-duplicate loc/iloc examples into one rule-first selection snippet.", + "Dropped low-value toy indexing examples that repeat the same distinction without adding a new exam pattern." + ] + }, + { + "id": "working-with-values", + "title": "Working With Values", + "sections": { + "must_know": [ + { + "title": "Default mental model: vectorized column expressions first, `map`/`apply` only when needed", + "summary": "If the job is straightforward arithmetic or string work that pandas already supports elementwise, write the expression directly. Use `Series.map(...)` for one value in -> one value out on a single Series. Use `DataFrame.apply(..., axis=1)` only when the logic genuinely needs multiple columns from the same row.", + "example": "df['total'] = df['A'] + df['B']\ns.map(lambda x: x + 1)\ndf.apply(lambda row: row['A'] + row['B'], axis=1)", + "why_kept": "This merges the strongest surviving Week 5 value-transformation rules into one exam-usable decision rule.", + "source_basis": [ + "manual-pandas-values", + "kp-5-d2", + "kp-5", + "kp-6" + ] + }, + { + "title": "Filter first, then aggregate or sort", + "summary": "A very common exam pattern is: build a mask, select rows or one column, then run `sum()`, `mean()`, `count()`, or `sort_values(...)` on the result.", + "example": "mask = df['A'] > 0\nresult = df.loc[mask, 'B'].mean()\ndf.sort_values('B', ascending=False)", + "why_kept": "This is one of the most reusable pandas exam workflows and deserves its own must-know summary.", + "source_basis": [ + "manual-pandas-filter-aggregate", + "kp-manual-filter-aggregate-d2", + "manual-pandas-values" + ] + }, + { + "title": "Use the vectorized text tools pandas already gives you", + "summary": "Use `.str` methods for built-in string operations over a whole Series, and `isin(...)` for membership tests over many values at once.", + "example": "s.str.upper().str.count('A')\ndf[df['city'].isin(['A', 'B'])]", + "why_kept": "This is clearer and more compact than shipping separate tiny snippets for `.str`, `isin`, and string filtering.", + "source_basis": [ + "ks-115ab52188", + "ks-2bed6c308f", + "kp-3", + "kp-4" + ] + }, + { + "title": "Choose between vectorized math, `map`, and `apply` with a quick table", + "summary": "This restores one of the high-value decision aids that is easy to scan under exam pressure.", + "pieces": [ + { + "id": "pandas-map-apply-table", + "piece_type": "reference_table", + "title": "Value-transformation decision table", + "content": { + "headers": [ + "Need", + "Use", + "Example" + ], + "rows": [ + [ + "simple column arithmetic", + "vectorized expression", + "df['A'] + df['B']" + ], + [ + "one value in -> one value out on a Series", + "Series.map(...)", + "s.map(lambda x: x + 1)" + ], + [ + "row logic using multiple columns", + "DataFrame.apply(..., axis=1)", + "df.apply(lambda row: row['A'] + row['B'], axis=1)" + ] + ], + "text": "Use the simplest shape-preserving option that matches the task." + }, + "source_refs": [ + "manual-pandas-values", + "kp-5", + "kp-6" + ] + } + ], + "source_refs": [ + "manual-pandas-values", + "kp-5", + "kp-6" + ] + } + ], + "exam_patterns": [ + { + "title": "Text splitting: choose output shape on purpose", + "summary": "If you want one derived Series, `map(...)` can be enough. If you want multiple new DataFrame columns, use `.str.split(..., expand=True)`.", + "pattern": "s.map(lambda x: x.split('; ')[0])\n# or\ndf[['municipality', 'province']] = df['place'].str.split('; ', expand=True)", + "watch_out": [ + "Do not treat `Series.split(...)` as if pandas strings worked like plain Python strings.", + "Choose `expand=True` only when the target is multiple columns." + ], + "source_basis": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "manual-pandas-split-into-columns" + ] + }, + { + "title": "Missing values: decide whether to keep shape or drop data", + "summary": "Use `.fillna(...)` if you want to preserve the table and replace missing values. Use `.dropna()` when incomplete rows or columns should disappear entirely.", + "pattern": "df.fillna('No value')\ndf.dropna()", + "source_basis": [ + "kp-manual-drop-missing", + "ks-18a9645168" + ] + } + ], + "useful_backup": [ + { + "title": "Sorting and scalar broadcasting are good support patterns, not front-page content", + "summary": "Keep `sort_values(...)` vs `sort_index(...)` and scalar broadcasting in reserve because they matter, but they are less often the decisive snippet than filtering, shape, and map/apply decisions.", + "example": "df.sort_values(by='score', ascending=False)\ndf['Height'] += 10", + "why_backup": "These belong in backup because they are useful follow-ups, not the clearest parent-topic anchors.", + "source_basis": [ + "ai-example-1", + "ai-example-2", + "ks-f8eec928e1" + ] + } + ] + }, + "dropped_or_merged": [ + "Merged separate snippets for sort, map, apply, isin, and string methods into a smaller set of decision rules.", + "Dropped weak standalone one-liners such as isolated `drop(...)`/`dropna()` examples unless they supported a broader exam pattern." + ] + } + ] +} diff --git a/data/manual_curation_drafts/python_foundations.json b/data/manual_curation_drafts/python_foundations.json new file mode 100644 index 0000000..f7d8db1 --- /dev/null +++ b/data/manual_curation_drafts/python_foundations.json @@ -0,0 +1,1058 @@ +{ + "id": "python-foundations", + "title": "Python Foundations", + "summary": "Core syntax, name/object reasoning, operator logic, and condition-building rules that recur across the early-course exams. This manual draft keeps only dense, exam-useful material and removes noisy cross-topic spillover from the generated intake.", + "source_refs": { + "exam_builder_parent_topic": "python-foundations", + "topic_card_ids": [ + "w1-python-basics", + "w1-objects-and-names", + "w1-operators-and-truth", + "w2-conditions" + ], + "review_packets": [] + }, + "main_topics": [ + { + "id": "python-basics", + "title": "Python Basics", + "summary": "Read code literally: know what Python ignores, how one statement can span lines, and which backslashes do or do not create escapes.", + "source_refs": { + "topic_card_id": "w1-python-basics", + "exam_builder_topic_id": "python-basics" + }, + "sections": { + "must_know": { + "snippets": [ + { + "id": "python-basics-syntax-rules", + "title": "Comments, Logical Lines, and Raw Strings", + "summary": "Most beginner syntax mistakes here come from forgetting what `#` ignores, when Python allows line continuation, and how raw strings treat backslashes.", + "source_refs": { + "exam_builder_snippet_ids": [ + "snippet-subtopic-w1-python-basics-w1-python-basics-execution-model", + "snippet-item-manual-comments", + "snippet-item-manual-logical-lines" + ], + "topic_card_piece_ids": [ + "manual-comments", + "manual-logical-lines", + "ai-example-4", + "ai-example-5", + "ai-example-6" + ] + }, + "pieces": [ + { + "id": "python-basics-syntax-rules-table", + "piece_type": "reference_table", + "title": "Syntax rules you should recall instantly", + "content": { + "headers": [ + "Pattern", + "What Python does", + "Example" + ], + "rows": [ + [ + "# comment", + "ignores everything after `#` on that logical line", + "x = 3 # ignored text" + ], + [ + "open brackets", + "statement can continue on later physical lines", + "nums = [\\n 1,\\n 2\\n]" + ], + [ + "backslash `\\\\`", + "explicitly continues one statement onto the next line", + "a = 'hi' + \\\\\\n ' there'" + ], + [ + "raw string `r'...'`", + "backslashes are kept literally; quotes still must match", + "r'c:\\\\temp\\\\file.txt'" + ] + ] + }, + "source_refs": { + "derived_from": [ + "manual-comments", + "manual-logical-lines", + "ai-example-4", + "ai-example-5", + "ai-example-6" + ] + } + }, + { + "id": "python-basics-syntax-rules-code", + "piece_type": "code_example", + "title": "Compact syntax examples", + "content": { + "code": "x = 3 # comment does not execute\\nprint(x)\\n\\npath = r'c:\\\\new\\\\folder'\\n\\nnumbers = [\\n 1,\\n 2,\\n 3,\\n]", + "note": "Use brackets whenever possible; use an explicit backslash only when there is no bracketed structure to hold the continuation." + }, + "source_refs": { + "derived_from": [ + "manual-comments", + "manual-logical-lines", + "ai-example-4" + ] + } + } + ] + }, + { + "id": "python-basics-escape-sequences", + "title": "Escape Sequences and Quote Choices", + "summary": "Keep one tiny reference for newline, tab, backslash, and quote escaping so you do not have to reconstruct them from memory in a syntax question.", + "source_refs": { + "topic_card_piece_ids": [ + "ai-example-4", + "ai-example-7", + "manual-string-literals-example" + ] + }, + "pieces": [ + { + "id": "python-basics-escape-sequences-table", + "piece_type": "reference_table", + "title": "Small escapes worth recognizing instantly", + "content": { + "headers": [ + "Pattern", + "Meaning", + "Example output" + ], + "rows": [ + [ + "\\n", + "newline", + "Line 1 then Line 2 on the next line" + ], + [ + "\\t", + "tab", + "horizontal spacing" + ], + [ + "\\\\", + "literal backslash", + "c:\\\\new\\\\folder" + ], + [ + "quote escape", + "literal quote inside a string", + "use the other quote style or escape it" + ] + ], + "text": "This is intentionally tiny: it is here for exact syntax and output questions, not for prose explanation." + }, + "source_refs": { + "derived_from": [ + "ai-example-4", + "ai-example-7", + "manual-string-literals-example" + ] + } + } + ] + } + ] + }, + "exam_patterns": { + "snippets": [ + { + "id": "python-basics-read-it-literally", + "title": "Read Tiny Syntax Fragments Literally", + "summary": "Week-1 basics questions are often solved by tracing exactly what Python reads, not by overthinking intent.", + "source_refs": { + "topic_card_piece_ids": [ + "cs-09e2b215ee", + "cs-7498cfc507", + "cs-814a07a136" + ] + }, + "pieces": [ + { + "id": "python-basics-read-it-literally-code", + "piece_type": "code_example", + "title": "Literal reading beats guessing", + "content": { + "code": "print('Hello World') # prints only Hello World\\n# print(_, __, ___) -> the whole line is a comment if it starts with #\\n123 * 1 # plain arithmetic, no hidden meaning", + "note": "If Python sees a valid literal expression, it evaluates that expression only. Ignore the story in your head and trace the actual tokens." + }, + "source_refs": { + "derived_from": [ + "cs-09e2b215ee", + "cs-7498cfc507", + "cs-814a07a136" + ] + } + } + ] + } + ] + }, + "useful_backup": { + "snippets": [ + { + "id": "python-basics-execution-model", + "title": "Execution Precision Mental Model", + "summary": "Useful as a fallback reminder when two syntax options look similar.", + "source_refs": { + "topic_card_piece_ids": [ + "kp-1", + "ks-95be7f9418" + ] + }, + "pieces": [ + { + "id": "python-basics-execution-model-text", + "piece_type": "explanation", + "title": "Python is precise, not forgiving", + "content": { + "text": "Python translates your script step by step, so tiny syntax differences matter. If two options look almost the same, assume Python will care about the exact tokens, indentation, and delimiters." + }, + "source_refs": { + "derived_from": [ + "kp-1", + "ks-95be7f9418" + ] + } + } + ] + } + ] + } + } + }, + { + "id": "objects-and-names", + "title": "Objects and Names", + "summary": "Know what a name points to, which objects can change in place, and when code is creating a new object versus sharing the old one.", + "source_refs": { + "topic_card_id": "w1-objects-and-names", + "exam_builder_topic_id": "objects-and-names" + }, + "sections": { + "must_know": { + "snippets": [ + { + "id": "objects-and-names-binding", + "title": "Names Bind to Objects", + "summary": "This is the main mental model: names point at objects; rebinding changes the name-object link, while mutation changes a mutable object in place.", + "source_refs": { + "topic_card_piece_ids": [ + "kp-1", + "kp-3", + "kp-9" + ] + }, + "pieces": [ + { + "id": "objects-and-names-binding-table", + "piece_type": "reference_table", + "title": "What changes in each case?", + "content": { + "headers": [ + "Action", + "Effect", + "Example" + ], + "rows": [ + [ + "rebind a name", + "name points to a different object", + "x = 3; x = '3'" + ], + [ + "mutate a list/dict/set", + "same object, changed contents", + "lst[0] = 99" + ], + [ + "call a method on an immutable value", + "usually returns a new object; original stays unchanged", + "s = 'abc'; s.upper()" + ] + ] + }, + "source_refs": { + "derived_from": [ + "kp-1", + "kp-3", + "aiq-2" + ] + } + }, + { + "id": "objects-and-names-binding-code", + "piece_type": "code_example", + "title": "Rebinding versus mutation", + "content": { + "code": "name = [1, 2, 3]\\nalias = name\\nname[0] = 99\\nprint(alias) # [99, 2, 3]\\n\\ns = 'abc'\\ns.upper()\\nprint(s) # 'abc' (unchanged)", + "note": "Lists are mutable; strings are not. A method call on a string does not update the original variable unless you reassign." + }, + "source_refs": { + "derived_from": [ + "kp-2", + "kp-manual-aliasing-copy", + "aiq-2" + ] + } + } + ] + }, + { + "id": "objects-and-names-mutable-vs-immutable", + "title": "Mutable, Immutable, and Copying", + "summary": "Many exam traps reduce to three questions: is the object mutable, are two names sharing it, and did slicing create a copy?", + "source_refs": { + "topic_card_piece_ids": [ + "kp-2", + "kp-6", + "kp-manual-aliasing-copy" + ] + }, + "pieces": [ + { + "id": "objects-and-names-mutable-vs-immutable-table", + "piece_type": "reference_table", + "title": "Fast mutability check", + "content": { + "headers": [ + "Type", + "Mutable?", + "Typical trap" + ], + "rows": [ + [ + "int, float, str, tuple", + "no", + "operation gives a new value/object" + ], + [ + "list, dict, set", + "yes", + "an alias sees in-place changes" + ], + [ + "slice `seq[:]`", + "new object", + "copy of the outer sequence" + ] + ] + }, + "source_refs": { + "derived_from": [ + "kp-2", + "kp-6", + "kp-manual-aliasing-copy" + ] + } + }, + { + "id": "objects-and-names-mutable-vs-immutable-code", + "piece_type": "code_example", + "title": "Aliasing versus slicing copy", + "content": { + "code": "l1 = [1, 2, 3]\\nl2 = l1\\nl3 = l1[:]\\nl1[0] = 99\\nprint(l2) # [99, 2, 3]\\nprint(l3) # [1, 2, 3]", + "note": "`l2 = l1` shares the same list. `l1[:]` creates a new outer list." + }, + "source_refs": { + "derived_from": [ + "kp-manual-aliasing-copy-d1", + "aiq-6" + ] + } + } + ] + } + ] + }, + "exam_patterns": { + "snippets": [ + { + "id": "objects-and-names-slicing-and-range-trace", + "title": "Trace Slices and Indexed Assignment Carefully", + "summary": "These questions are usually about excluded stop values, negative indices, or using values as indices by mistake.", + "source_refs": { + "topic_card_piece_ids": [ + "aiq-3", + "kp-6-d1", + "kp-6-d2" + ] + }, + "pieces": [ + { + "id": "objects-and-names-slicing-and-range-trace-text", + "piece_type": "explanation", + "title": "Three rules that resolve most slice questions", + "content": { + "text": "For `seq[start:end:step]`, start is included, end is excluded, and a negative step walks right-to-left. When squaring list elements with a loop over indices, use `range(len(x))`, not the element values themselves." + }, + "source_refs": { + "derived_from": [ + "aiq-3", + "kp-6" + ] + } + }, + { + "id": "objects-and-names-slicing-and-range-trace-code", + "piece_type": "code_example", + "title": "Correct index-based update pattern", + "content": { + "code": "mylist = [0] * len(x)\\nfor i in range(len(x)):\\n mylist[i] = x[i] ** 2", + "note": "Looping with `for i in x` gives element values, not safe positions." + }, + "source_refs": { + "derived_from": [ + "aiq-3" + ] + } + } + ] + }, + { + "id": "objects-and-names-mutable-defaults", + "title": "Mutable Default Argument Trap", + "summary": "A default list or dict is created once when the function is defined, not each time the function is called.", + "source_refs": { + "topic_card_piece_ids": [ + "aiq-7" + ] + }, + "pieces": [ + { + "id": "objects-and-names-mutable-defaults-code", + "piece_type": "code_example", + "title": "Use `None`, then create the object inside", + "content": { + "code": "def f(lst=None):\\n if lst is None:\\n lst = []\\n return lst", + "note": "This avoids sharing one default list across multiple calls." + }, + "source_refs": { + "derived_from": [ + "aiq-7" + ] + } + } + ] + } + ] + }, + "useful_backup": { + "snippets": [ + { + "id": "objects-and-names-builtins-and-naming", + "title": "Core Types and Naming Rules", + "summary": "Low-friction reference material for early exam questions.", + "source_refs": { + "topic_card_piece_ids": [ + "kp-4", + "kp-5" + ] + }, + "pieces": [ + { + "id": "objects-and-names-builtins-and-naming-table", + "piece_type": "reference_table", + "title": "Built-in types and name rules", + "content": { + "headers": [ + "Thing", + "Remember" + ], + "rows": [ + [ + "core types", + "`int`, `float`, `str`, `bool`, `tuple`, `list`, `dict`, `set`" + ], + [ + "valid names", + "letters, digits, underscores; cannot start with a digit" + ], + [ + "case sensitivity", + "`name` and `Name` are different" + ], + [ + "avoid shadowing", + "do not reuse names like `list`, `print`, `sorted`" + ] + ] + }, + "source_refs": { + "derived_from": [ + "kp-4", + "kp-5" + ] + } + } + ] + } + ] + } + } + }, + { + "id": "operators-and-truth", + "title": "Operators and Truth", + "summary": "Arithmetic, comparisons, and boolean logic questions are mostly about operator meaning, precedence, and a few recurring traps.", + "source_refs": { + "topic_card_id": "w1-operators-and-truth", + "exam_builder_topic_id": "operators-and-truth" + }, + "sections": { + "must_know": { + "snippets": [ + { + "id": "operators-and-truth-arithmetic-reference", + "title": "Arithmetic Operator Reference", + "summary": "The highest-yield early-operator facts are `/` vs `//`, `%`, `**`, and the reminder that `^` is not exponentiation.", + "source_refs": { + "topic_card_piece_ids": [ + "kp-1", + "ai-example-1" + ] + }, + "pieces": [ + { + "id": "operators-and-truth-arithmetic-reference-table", + "piece_type": "reference_table", + "title": "Arithmetic operators at a glance", + "content": { + "headers": [ + "Operator", + "Meaning", + "Example" + ], + "rows": [ + [ + "/", + "true division, returns float", + "4 / 2 -> 2.0" + ], + [ + "//", + "floor division", + "5 // 2 -> 2" + ], + [ + "%", + "remainder", + "5 % 2 -> 1" + ], + [ + "**", + "exponentiation", + "4 ** 3 -> 64" + ], + [ + "^", + "bitwise XOR, not power", + "do not use for exponentiation" + ] + ] + }, + "source_refs": { + "derived_from": [ + "kp-1" + ] + } + }, + { + "id": "operators-and-truth-arithmetic-reference-code", + "piece_type": "code_example", + "title": "Floor division and modulo identity", + "content": { + "code": "print(5 // 3, 5 % 3)\\nprint(-5 // 3, -5 % 3)\\n# (a // b) * b + a % b == a", + "note": "This identity is reliable even when negative numbers make the floor result look surprising." + }, + "source_refs": { + "derived_from": [ + "ai-example-1" + ] + } + } + ] + }, + { + "id": "operators-and-truth-comparison-and-logic", + "title": "Comparison and Boolean Logic", + "summary": "Comparison operators return booleans, and precedence is a common exam trap.", + "source_refs": { + "topic_card_piece_ids": [ + "kp-2", + "kp-3", + "ai-example-4", + "ai-example-8" + ] + }, + "pieces": [ + { + "id": "operators-and-truth-comparison-and-logic-table", + "piece_type": "reference_table", + "title": "Comparison and logic rules", + "content": { + "headers": [ + "Rule", + "Remember" + ], + "rows": [ + [ + "comparison result", + "`==`, `!=`, `<`, `>`, `<=`, `>=` always produce `True` or `False`" + ], + [ + "`==` vs `is`", + "`==` compares value; `is` compares object identity" + ], + [ + "precedence", + "`not` before `and`, and `and` before `or`" + ], + [ + "safe habit", + "add parentheses when the intended grouping is not obvious" + ] + ] + }, + "source_refs": { + "derived_from": [ + "kp-2", + "kp-3", + "ai-example-8" + ] + } + }, + { + "id": "operators-and-truth-comparison-and-logic-code", + "piece_type": "code_example", + "title": "Precedence trap", + "content": { + "code": "a = 1; b = 3\\nprint(a == 1 or a == 2 and b == 1 or b == 2)\\nprint((a == 1 or a == 2) and (b == 1 or b == 2))", + "note": "The first line is parsed as `a == 1 or (a == 2 and b == 1) or b == 2`." + }, + "source_refs": { + "derived_from": [ + "ai-example-4" + ] + } + } + ] + } + ] + }, + "exam_patterns": { + "snippets": [ + { + "id": "operators-and-truth-negative-floor-division", + "title": "Negative Floor-Division and Modulo", + "summary": "This exact pattern recurs because students often expect truncation toward zero instead of flooring.", + "source_refs": { + "topic_card_piece_ids": [ + "ai-example-1", + "cs-266616a010" + ] + }, + "pieces": [ + { + "id": "operators-and-truth-negative-floor-division-code", + "piece_type": "code_example", + "title": "Outputs with negative numerators", + "content": { + "code": "print(-5 // 3, -5 % 3) # -2 1\\nprint(-5 // 2, -5 % 2) # -3 1", + "note": "`//` rounds down to the next lower integer, so it can be smaller than simple truncation." + }, + "source_refs": { + "derived_from": [ + "ai-example-1", + "cs-266616a010" + ] + } + } + ] + }, + { + "id": "operators-and-truth-float-and-sequence-traps", + "title": "Float Precision and Ordered Comparison Traps", + "summary": "The exam often mixes one numeric precision surprise with one ordered-versus-unordered comparison surprise.", + "source_refs": { + "topic_card_piece_ids": [ + "ai-example-2", + "ai-example-3" + ] + }, + "pieces": [ + { + "id": "operators-and-truth-float-and-sequence-traps-code", + "piece_type": "code_example", + "title": "Two classic comparison pitfalls", + "content": { + "code": "print(1.1 + 2.2 == 3.3) # False\\nprint([1, 2] == [2, 1]) # False\\nprint({1, 2} == {2, 1}) # True", + "note": "Lists/tuples/strings are ordered. Sets and dict equality ignore insertion order." + }, + "source_refs": { + "derived_from": [ + "ai-example-2", + "ai-example-3" + ] + } + } + ] + } + ] + }, + "useful_backup": { + "snippets": [ + { + "id": "operators-and-truth-quick-boolean-reminder", + "title": "Quick Boolean Reminder", + "summary": "Tiny fallback reminder when a condition question becomes a logic puzzle.", + "source_refs": { + "topic_card_piece_ids": [ + "kp-3" + ] + }, + "pieces": [ + { + "id": "operators-and-truth-quick-boolean-reminder-text", + "piece_type": "explanation", + "title": "`and`, `or`, `not` in one line", + "content": { + "text": "`x and y` is true only if both are true. `x or y` is false only if both are false. `not x` flips a boolean." + }, + "source_refs": { + "derived_from": [ + "kp-3" + ] + } + } + ] + }, + { + "id": "operators-and-truth-equality-vs-identity", + "title": "`==` compares values; `is` compares identity", + "summary": "This is a small but classic distractor, especially when two options print the same thing but use different operators.", + "source_refs": { + "topic_card_piece_ids": [ + "ai-example-8", + "kp-2" + ] + }, + "pieces": [ + { + "id": "operators-and-truth-equality-vs-identity-table", + "piece_type": "reference_table", + "title": "Value test versus identity test", + "content": { + "headers": [ + "Expression", + "Checks", + "Use it for" + ], + "rows": [ + [ + "a == b", + "same value", + "normal equality questions" + ], + [ + "a is b", + "same object in memory", + "identity / None checks" + ], + [ + "x is None", + "identity to the singleton None", + "preferred None check" + ] + ], + "text": "If the exam is not specifically about object identity, `==` is usually the intended operator." + }, + "source_refs": { + "derived_from": [ + "ai-example-8", + "kp-2" + ] + } + } + ] + } + ] + } + } + }, + { + "id": "conditions", + "title": "Conditions", + "summary": "Condition questions usually test three things: how branching syntax is structured, how truthiness and membership work, and whether compound logic is grouped correctly.", + "source_refs": { + "topic_card_id": "w2-conditions", + "exam_builder_topic_id": "conditions" + }, + "sections": { + "must_know": { + "snippets": [ + { + "id": "conditions-branching-and-ternary", + "title": "if / elif / else and Ternary Expressions", + "summary": "Know when to use a full branch block and when a single conditional expression is enough.", + "source_refs": { + "topic_card_piece_ids": [ + "ks-c19999c074", + "manual-conditional-expression", + "kp-manual-ternary" + ] + }, + "pieces": [ + { + "id": "conditions-branching-and-ternary-table", + "piece_type": "reference_table", + "title": "Branching choices", + "content": { + "headers": [ + "Form", + "Use it when", + "Example" + ], + "rows": [ + [ + "if / elif / else", + "branches need statements or multiple actions", + "full block with indentation" + ], + [ + "x if cond else y", + "you only need one resulting value", + "label = 'pass' if score >= 10 else 'fail'" + ] + ] + }, + "source_refs": { + "derived_from": [ + "ks-c19999c074", + "manual-conditional-expression", + "kp-manual-ternary" + ] + } + }, + { + "id": "conditions-branching-and-ternary-code", + "piece_type": "code_example", + "title": "Block form versus expression form", + "content": { + "code": "if score >= 18:\n label = 'excellent'\nelif score >= 10:\n label = 'pass'\nelse:\n label = 'fail'\n\nshort_label = 'pass' if score >= 10 else 'fail'", + "note": "Keep the full indented skeleton in mind for branch questions; use the ternary form only when one value is chosen." + }, + "source_refs": { + "derived_from": [ + "manual-conditional-expression", + "ks-c19999c074" + ] + } + } + ] + }, + { + "id": "conditions-truthiness-and-membership", + "title": "Truthiness and `in`", + "summary": "A lot of conditions can be solved by knowing which values are falsy and what membership tests actually check.", + "source_refs": { + "topic_card_piece_ids": [ + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core", + "ks-4b427a2425" + ] + }, + "pieces": [ + { + "id": "conditions-truthiness-and-membership-table", + "piece_type": "reference_table", + "title": "Truthy/falsy and membership rules", + "content": { + "headers": [ + "Pattern", + "Result", + "Remember" + ], + "rows": [ + [ + "[], (), {}, set(), '', 0, 0.0, None", + "falsy", + "empty/zero values fail a condition" + ], + [ + "non-empty collection / non-zero number", + "truthy", + "passes a condition" + ], + [ + "key in dict", + "checks keys", + "`4 in {1:4, 2:3}` is False" + ], + [ + "'1' in '123'", + "substring test", + "works on strings too" + ] + ] + }, + "source_refs": { + "derived_from": [ + "ks-4b427a2425", + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core" + ] + } + }, + { + "id": "conditions-truthiness-and-membership-code", + "piece_type": "code_example", + "title": "`in` examples worth memorizing", + "content": { + "code": "print(1 in [1, 2, 3]) # True\\nprint('1' in '123') # True\\nprint(1 in {1: 4, 2: 3}) # True\\nprint(4 in {1: 4, 2: 3}) # False", + "note": "For dictionaries, membership tests keys, not values." + }, + "source_refs": { + "derived_from": [ + "ks-4b427a2425" + ] + } + } + ] + } + ] + }, + "exam_patterns": { + "snippets": [ + { + "id": "conditions-precedence-trap", + "title": "Parenthesize Compound Conditions", + "summary": "A frequent exam pattern is that the unparenthesized condition is legal Python but means something different from what students intended.", + "source_refs": { + "topic_card_piece_ids": [ + "manual-bool-precedence", + "kp-manual-precedence", + "ai-example-1" + ] + }, + "pieces": [ + { + "id": "conditions-precedence-trap-code", + "piece_type": "code_example", + "title": "The classic precedence trap", + "content": { + "code": "a = 1; b = 3\\nprint(a == 1 or a == 2 and b == 1 or b == 2)\\nprint((a == 1 or a == 2) and (b == 1 or b == 2))", + "note": "If the logic matters, parenthesize. Do not rely on memory under exam pressure." + }, + "source_refs": { + "derived_from": [ + "manual-bool-precedence", + "kp-manual-precedence", + "ai-example-1" + ] + } + } + ] + }, + { + "id": "conditions-filtering-pattern", + "title": "Filter by Applying the Condition to Each Element", + "summary": "When a function accepts a `condition`, trace one element first and keep the elements where the condition returns `True`.", + "source_refs": { + "topic_card_piece_ids": [ + "manual-filter-condition", + "exam-trial_midterm-6-w2-conditions" + ] + }, + "pieces": [ + { + "id": "conditions-filtering-pattern-code", + "piece_type": "code_example", + "title": "Condition-driven filtering", + "content": { + "code": "def main(lst, condition):\\n return [x for x in lst if condition(x)]\\n\\nmain([1, 2, 3, 4], lambda x: x % 2 != 0) # [1, 3]", + "note": "The lambda keeps odd values here because `x % 2 != 0` is true only for odd numbers." + }, + "source_refs": { + "derived_from": [ + "manual-filter-condition", + "exam-trial_midterm-6-w2-conditions" + ] + } + } + ] + } + ] + }, + "useful_backup": { + "snippets": [ + { + "id": "conditions-explicit-conversion", + "title": "Convert Before Comparing Mixed Types", + "summary": "Useful backup for conditions that mix strings, ints, floats, and booleans.", + "source_refs": { + "topic_card_piece_ids": [ + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core", + "exam-midterm_2024-2-w2-conditions" + ] + }, + "pieces": [ + { + "id": "conditions-explicit-conversion-table", + "piece_type": "reference_table", + "title": "Common conversions and traps", + "content": { + "headers": [ + "Goal", + "Do this", + "Trap" + ], + "rows": [ + [ + "string to int", + "`int('3')`", + "`'3' == 3` is false because the types differ" + ], + [ + "string to float", + "`float('3.0')`", + "invalid numeric text raises `ValueError`" + ], + [ + "numeric truth", + "`0` is false, non-zero is true", + "`True == 1` and `False == 0` in numeric contexts" + ], + [ + "invalid integer text", + "int('1a')", + "raises `ValueError`" + ], + [ + "mix string and int directly", + "str(1) + \"2\" or int(\"2\") + 1", + "'1' + 2 raises `TypeError`" + ] + ] + }, + "source_refs": { + "derived_from": [ + "snippet-subtopic-w2-conversion-and-truthiness-w2-conversion-and-truthiness-core", + "exam-midterm_2024-2-w2-conditions" + ] + } + } + ] + } + ] + } + } + } + ] +} diff --git a/data/manual_curation_drafts/strings_and_output.json b/data/manual_curation_drafts/strings_and_output.json new file mode 100644 index 0000000..09e7cdc --- /dev/null +++ b/data/manual_curation_drafts/strings_and_output.json @@ -0,0 +1,409 @@ +{ + "parent_topic_id": "strings-and-output", + "parent_topic_title": "Strings and Output", + "topics": [ + { + "id": "string-fundamentals", + "title": "String Fundamentals", + "must_know": [ + { + "title": "Strings are immutable", + "source_ids": [ + "kp-1", + "ks-b734a22f46", + "manual-string-immutability" + ], + "text": "String methods return new strings. If you want the change to persist, assign the result back to a variable.", + "code": "s = 'abcd'\ns = s.upper()" + }, + { + "title": "Escape characters and literal quotes", + "source_ids": [ + "kp-2", + "ks-309158a68c", + "manual-string-literals-example" + ], + "text": "Use the other quote style or escape the inner quote. Keep three patterns in mind: backslash-n makes a newline, backslash-t makes a tab, and escaped quotes let the string stay open.", + "code": "print(\"it\\'s\")\nprint('He said \"hi\"')" + }, + { + "title": "Length and indexing basics", + "source_ids": [ + "ai-example-8", + "cs-bb7b598ca1" + ], + "text": "len(s) counts every character in the string, and indexing starts at 0.", + "code": "a = 'adbc'\nprint(len(a))" + } + ], + "exam_patterns": [ + { + "title": "Rebuild strings instead of assigning into them", + "source_ids": [ + "kp-3", + "manual-string-immutability" + ], + "text": "If an exam asks to change one character, rebuild the string with slicing instead of assigning by index.", + "code": "s = 'A' + s[1:]" + }, + { + "title": "Filter characters in a loop", + "source_ids": [ + "ai-example-4", + "cs-14245b8c1f" + ], + "text": "Use a running result string when the question asks you to keep only the characters that pass a test.", + "code": "text = 'AbCde'\nresult = ''\nfor ch in text:\n if ch.islower():\n result += ch\nprint(result) # 'bde'" + } + ], + "useful_backup": [ + { + "title": "Repeat text with *", + "source_ids": [ + "manual-string-repetition" + ], + "text": "The * operator repeats a string, which sometimes appears in short output questions.", + "code": "print(3 * 'ha')" + }, + { + "title": "Uppercase helper loop", + "source_ids": [ + "ai-example-4", + "cs-14245b8c1f" + ], + "text": "A tiny helper can make a filtering loop readable when the test itself is part of what the exam is asking about.", + "code": "def my_isupper(s1):\n return s1 == s1.upper() and s1 != s1.lower()\n\nresult = ''\nfor ch in 'AbCdeF':\n if my_isupper(ch):\n result += ch\nprint(result) # 'ACF'" + }, + { + "title": "Escape-sequence quick table", + "summary": "A compact backup table for the escape and quote patterns that still show up in tiny output questions.", + "pieces": [ + { + "id": "string-fundamentals-escape-table", + "piece_type": "reference_table", + "title": "Escapes and quote-safe patterns", + "content": { + "headers": [ + "Pattern", + "Meaning", + "Example" + ], + "rows": [ + [ + "backslash-n", + "newline", + "\"Line 1\\nLine 2\"" + ], + [ + "backslash-t", + "tab", + "\"A\\tB\"" + ], + [ + "escaped quote", + "literal quote", + "\"it\\'s\" or 'He said \"hi\"'" + ], + [ + "raw string r\"...\"", + "keep backslashes literal", + "r\"c:\\\\temp\\\\file.txt\"" + ] + ], + "text": "Keep this low on the page, but it is worth having when a syntax fragment has to be read exactly." + }, + "source_refs": [ + "manual-string-literals-example", + "manual-string-immutability" + ] + } + ], + "source_refs": [ + "manual-string-literals-example" + ] + } + ] + }, + { + "id": "string-operations-and-methods", + "title": "String Operations and Methods", + "must_know": [ + { + "title": "find() versus index()", + "source_ids": [ + "kp-1", + "kp-7", + "ai-example-1", + "manual-find-vs-index" + ], + "text": ".find() returns -1 when the substring is missing; .index() raises ValueError.", + "code": "s = 'abc'\nprint(s.find('z'))\n# print(s.index('z')) # ValueError" + }, + { + "title": "split() and join() round-trip", + "source_ids": [ + "kp-3", + "ai-example-3", + "manual-string-output-construction" + ], + "text": ".split() turns text into a list, and .join() turns a list back into text with a separator.", + "code": "words = 'a b c'.split()\nprint('-'.join(words))" + }, + { + "title": "replace() returns a new string", + "source_ids": [ + "kp-4", + "ai-example-4", + "kp-manual-string-method-results-d1" + ], + "text": ".replace(old, new, count) creates a new string and can limit how many replacements happen.", + "code": "s = 'aaaa'\nprint(s.replace('a', 'b', 2))" + } + ], + "exam_patterns": [ + { + "title": "Step slicing and reverse order", + "source_ids": [ + "kp-2", + "ai-example-2", + "manual-string-indexing-reference" + ], + "text": "Use s[::2] for every second character, s[::-1] to reverse, and negative indices to count from the end.", + "code": "s = '01234567'\nprint(s[::2])\nprint(s[::-1])" + }, + { + "title": "Boolean string predicates", + "source_ids": [ + "kp-9", + "manual-string-islower-method" + ], + "text": ".islower(), .isupper(), and .isdigit() only return True when the string contains matching cased or digit characters.", + "code": "print('amsterdam'.islower())\nprint('123'.islower())" + }, + { + "title": "Trim whitespace and edges", + "source_ids": [ + "kp-6", + "ai-example-6", + "manual-string-method-results-d1" + ], + "text": ".strip() removes leading and trailing whitespace; lstrip() and rstrip() remove just one side.", + "code": "s = ' abc '\nprint(s.strip())" + } + ], + "useful_backup": [ + { + "title": "String module constants", + "source_ids": [ + "kp-5", + "ai-example-5" + ], + "text": "The string module provides ready-made constants such as ascii_lowercase and digits.", + "code": "import string\nprint(string.digits)" + }, + { + "title": "Search with start/stop", + "source_ids": [ + "ai-example-7", + "ai-example-8" + ], + "text": "find() and index() accept optional start and stop positions when a question needs a bounded search.", + "code": "s = 'abcdefgh'\nprint(s.find('e', 5))" + } + ], + "quick_tables": [ + { + "title": "String-method quick table", + "summary": "A compact scan table for the string methods that show up most often in exam options.", + "pieces": [ + { + "id": "string-methods-quick-table", + "piece_type": "reference_table", + "title": "Common string methods at a glance", + "content": { + "headers": [ + "Method", + "What it returns", + "Reminder" + ], + "rows": [ + [ + "s.find(sub)", + "index or -1", + "safe when missing" + ], + [ + "s.index(sub)", + "index or error", + "raises if missing" + ], + [ + "s.replace(a, b)", + "new string", + "string stays immutable" + ], + [ + "s.split(sep)", + "list of parts", + "text -> list" + ], + [ + "sep.join(parts)", + "new string", + "list -> text" + ], + [ + "s.strip()", + "trimmed string", + "edges only" + ] + ], + "text": "These are the highest-payoff methods to recognize instantly." + }, + "source_refs": [ + "manual-find-vs-index", + "manual-string-method-results-d1" + ] + } + ], + "source_refs": [ + "manual-find-vs-index", + "manual-string-method-results-d1" + ] + } + ] + }, + { + "id": "output-formatting", + "title": "Output Formatting", + "must_know": [ + { + "title": "f-strings for direct interpolation", + "source_ids": [ + "kp-1", + "ks-72dda5450c" + ], + "text": "F-strings embed expressions inside {} and are the cleanest way to build output strings.", + "code": "name = 'Jan'\nprint(f'{name} studies Python.')" + }, + { + "title": ".format() still appears in exams", + "source_ids": [ + "kp-4", + "ai-example-4", + "manual-string-format-method" + ], + "text": "The older .format() style still appears in exam questions and supports the same width and precision ideas.", + "code": "name = 'Jan'\nscore = 7\nprint('Student {} scored {:03d}'.format(name, score))" + }, + { + "title": "join() plus a custom tail", + "source_ids": [ + "ai-example-5", + "manual-output-formatting-code" + ], + "text": "Use join() for the repeated separator, then add the final custom wording separately.", + "code": "names = ['Ada', 'Linus', 'Grace']\nprint(', '.join(names[:-1]) + ', and ' + names[-1])" + } + ], + "exam_patterns": [ + { + "title": "Zero padding and decimal precision", + "source_ids": [ + "kp-3", + "ai-example-3", + "kp-5" + ], + "text": "Recognize formatting specs like {:03d} for zero padding and {:.1f} for one decimal place.", + "code": "print(f'{7:03d}')\nprint('{:.1f}'.format(7.25))" + }, + { + "title": "Debug output with f'{var=}'", + "source_ids": [ + "kp-2", + "ai-example-2" + ], + "text": "f'{var=}' prints both the variable name and the current value, which is easy to miss in answer choices.", + "code": "val = 10\nprint(f'{val=}')" + }, + { + "title": "Repeated output with *", + "source_ids": [ + "manual-string-repetition" + ], + "text": "The * operator repeats strings and can show up in quick output questions.", + "code": "print('ha' * 3)" + } + ], + "useful_backup": [ + { + "title": "Legacy format width", + "source_ids": [ + "kp-4", + "ai-example-4" + ], + "text": "'{:04d}'.format(n) is the non-f-string version of zero padding and is still worth recognizing.", + "code": "print('{:04d}'.format(7))" + }, + { + "title": "Build the middle, then patch the tail", + "source_ids": [ + "manual-output-formatting-code" + ], + "text": "When the last item needs special wording, format the repeated middle first and then patch on the ending.", + "code": "body = ', '.join(names[:-1])" + } + ], + "quick_tables": [ + { + "title": "Formatting mini table", + "summary": "A small reference for the format specs and output-building patterns that are easiest to forget under pressure.", + "pieces": [ + { + "id": "output-format-mini-table", + "piece_type": "reference_table", + "title": "Output formatting mini table", + "content": { + "headers": [ + "Pattern", + "Meaning" + ], + "rows": [ + [ + "f'{name}'", + "embed a value directly" + ], + [ + "{:03d}", + "integer with zero padding" + ], + [ + "{:.1f}", + "one decimal place" + ], + [ + "', '.join(names)", + "separator between repeated items" + ], + [ + "f'{var=}'", + "show name and value together" + ] + ], + "text": "This keeps the highest-value formatting specs in one place." + }, + "source_refs": [ + "manual-string-format-method", + "manual-output-formatting-code" + ] + } + ], + "source_refs": [ + "manual-string-format-method", + "manual-output-formatting-code" + ] + } + ] + } + ] +} diff --git a/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md b/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md index ab5bf53..487881e 100644 --- a/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md +++ b/data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md @@ -12,7 +12,13 @@ Runbook: ## Current Objective -Implement approved completeness improvements from the manual synthesis round without drifting into UI/topic-architecture refactors. +Run the fresh post-implementation grading pass on the updated snippet corpus, using the revised round-2 grading rules without drifting into UI/topic-architecture refactors. + +## Human Review Gates + +- Passed: the round-1 manual synthesis review gate has already been satisfied by the approved decisions in `plan_after_manual_synthesis.md`. +- Active overnight goal: implement the approved snippet-completeness work. +- Next hard gate: stop before aggressive pruning, topic/UI restructuring, or final ranking/category decisions based on the post-implementation corpus. ## State Snapshot @@ -24,39 +30,79 @@ python3 scripts/vision_exam_pipeline.py status --round round1 ## Cluster Tracker -- [ ] Essential String Methods and Indexing Reference -- [ ] Output Formatting and String Construction -- [ ] Boolean String Predicates -- [ ] Iteration Helpers and Basic Operator Traps -- [ ] Comprehension Syntax Reference -- [ ] Dictionary Construction and Iteration Patterns -- [ ] Pandas Selection and Indexing Rules -- [ ] Pandas Filtering, Aggregation, and Column Arithmetic (expand existing) -- [ ] Lambda, `map`, and `apply` -- [ ] Datetime Parse/Format + object-vs-string arithmetic reference family -- [ ] OOP Fundamentals -- [ ] OOP Comparison Logic (add or merge into existing) -- [ ] Flexible Arguments, Returns, and `kwargs` -- [ ] Return-Value and Scope Cleanup (edit existing) -- [ ] Exact-Match Retrieval Fixes (light and fair only) +- [x] Essential String Methods and Indexing Reference +- [x] Output Formatting and String Construction +- [x] Boolean String Predicates +- [x] Iteration Helpers and Basic Operator Traps +- [x] Comprehension Syntax Reference +- [x] Dictionary Construction and Iteration Patterns +- [x] Pandas Selection and Indexing Rules +- [x] Pandas Filtering, Aggregation, and Column Arithmetic (expand existing) +- [x] Lambda, `map`, and `apply` +- [x] Datetime Parse/Format + object-vs-string arithmetic reference family +- [x] OOP Fundamentals +- [x] OOP Comparison Logic (add or merge into existing) +- [x] Flexible Arguments, Returns, and `kwargs` +- [x] Return-Value and Scope Cleanup (edit existing) +- [x] Exact-Match Retrieval Fixes (light and fair only) ## In Progress -- Owner: -- Cluster: +- Owner: main supervisor +- Cluster: Round 2 snippet grading pass - Files: + - `data/vision_exam_pipeline/evaluations/round2.json` + - `data/vision_exam_pipeline/analytics/round2.json` + - `data/vision_exam_pipeline/analytics/round2.md` - Notes: + - Round 2 uses snippet-family aware evaluation fields and explicit near-identical past-exam piece detection. + - Full grading run should finish before any topic-categorisation or ranking-bucket implementation. ## Completed -- Timestamp: -- Cluster: -- Summary: -- Validation: +- Timestamp: 2026-03-24 02:24 CET +- Cluster: OOP Fundamentals; OOP Comparison Logic; Flexible Arguments, Returns, and `kwargs`; Return-Value and Scope Cleanup; Exact-Match Retrieval Fixes +- Summary: Finished the remaining approved support work inside existing cards instead of creating new architecture. OOP updates landed in `w4-oop-fundamentals`; flexible signatures landed in `w3-arguments`; return-value traps landed in `w3-return-behavior` and `w3-defining-and-calling-functions`; scope cleanup landed in `w3-scope`. Light retrieval cleanup was limited to clearer titles, whys, and missing subtopic item references for manual/AI support pieces only. +- Validation: targeted touched-card integrity checks and `ast.parse` passed, then `make leave-better` passed. `maintenance_audit.py` remained `warn` with 0 failures / 1 warning. + +- Timestamp: 2026-03-24 02:15 CET +- Cluster: Pandas Selection and Indexing Rules; Pandas Filtering, Aggregation, and Column Arithmetic; Lambda, `map`, and `apply`; Datetime Parse/Format + object-vs-string arithmetic reference family +- Summary: Expanded existing Week 5 and Week 6 anchors instead of creating detached cards. Selection/indexing rules landed in `w5-pandas-core-structures` and `w5-inspecting-and-selecting-data`; filtering/aggregation/column arithmetic plus Pandas `map`/`apply` landed in `w5-working-with-values`; lambda/map reference cleanup landed in `w3-higher-order-patterns`; datetime format-code and object-vs-string arithmetic pieces landed in `w6-datetime`. Changes stayed reference-first and preserved the strongest existing exam snippets. +- Validation: `python3 scripts/vision_exam_pipeline.py status --round round1`, targeted `ast.parse` on touched snippet code, and `make leave-better` all passed. `maintenance_audit.py` remained `warn` with 0 failures / 1 warning. + +- Timestamp: 2026-03-24 03:05 Europe/Amsterdam +- Cluster: Essential String Methods and Indexing Reference; Output Formatting and String Construction; Boolean String Predicates; Iteration Helpers and Basic Operator Traps; Comprehension Syntax Reference; Dictionary Construction and Iteration Patterns +- Summary: Added conservative reference-first completeness coverage in `topic_cards.json` without UI/topic restructuring. String work landed in `w4-string-operations-and-methods` and `w4-string-formatting`; loops/dicts/comprehensions work landed in `w2-loops`, `w2-dictionaries-and-mappings`, and `w6-comprehensions`. Existing strong exam anchors were preserved; new additions were mostly compact tables + selective examples. +- Validation: `make leave-better` passed. `maintenance_audit.py` returned `warn` with 0 failures / 1 warning. ## Blockers / Risks -- None yet. +- Existing dataset still contains at least one legacy code snippet with a non-printable character; targeted parsing on newly added snippets passed, but full `ast.parse` across every existing example was not used as a blocking validator because the repo already contains unrelated legacy invalid code text. +- The pipeline `status` command still reports `next_gate = human_review_of_synthesized_changes`, but for this overnight pass that earlier gate was intentionally overridden by the recorded human approvals in `plan_after_manual_synthesis.md`. +- Safe overnight implementation work from the approved cluster list is exhausted; the next safe step is the post-implementation grading/review pass, not more speculative snippet churn. +- Round 2 analytics should be treated as the first useful evidence for topic co-usage and ranking, but not yet as a final UI-restructuring mandate. + +Timestamp: +Completed: +- OOP Fundamentals +- OOP Comparison Logic (add or merge into existing) +- Flexible Arguments, Returns, and `kwargs` +- Return-Value and Scope Cleanup (edit existing) +- Exact-Match Retrieval Fixes (light and fair only) +In progress: +- None +Files touched: +- `topic_cards.json` +- `data/vision_exam_pipeline/OVERNIGHT_EXECUTION_BOARD.md` +Validation run: +- `python3 scripts/vision_exam_pipeline.py status --round round1` +- targeted `ast.parse` on touched snippet code +- `make leave-better` +Open risks: +- Next step should be the post-implementation grading/review flow rather than more overnight additions. +- Do not treat the existing `maintenance_audit.py` warning as a new blocker without checking the generated report. +Suggested next cluster: +- Stop overnight automation and hand off for the next human-guided grading/review gate ## Handoff Template diff --git a/data/vision_exam_pipeline/analytics/round2.json b/data/vision_exam_pipeline/analytics/round2.json new file mode 100644 index 0000000..6ab1ea0 --- /dev/null +++ b/data/vision_exam_pipeline/analytics/round2.json @@ -0,0 +1,528 @@ +{ + "schema_version": "1.0", + "generated_at": "2026-03-24T10:43:09Z", + "round": "round2", + "input_evaluations_path": "data/vision_exam_pipeline/evaluations/round2.json", + "summary": { + "total_evaluations": 168, + "completed_evaluations": 168, + "status_counts": { + "completed": 168 + }, + "answerability_counts": { + "certain": 61, + "insufficient": 71, + "partial": 36 + }, + "near_identical_repeat_piece_count": 42 + }, + "weeks": [ + { + "week": 1, + "top1_unique_snippets": 10, + "top3_unique_snippets": 16, + "minimal_set_unique_snippets": 17, + "minimal_set_unused_snippets": 73, + "unused_snippet_ids": [ + "item:aiq-6", + "item:aiq-7", + "item:cs-09e2b215ee", + "item:cs-23b2cfd4d6", + "item:cs-266616a010", + "item:cs-3cb4b8e8f9", + "item:cs-4155022ebf", + "item:cs-4f8a5f420b", + "item:cs-5b89a10dcd", + "item:cs-6d0d650063", + "item:cs-7eb8617d28", + "item:cs-814a07a136", + "item:cs-beb6591b24", + "item:cs-c25503e5db", + "item:cs-curated-hw-seq-nth-occurrence", + "item:cs-curated-hw-seq-slice-between-sentinels", + "item:exam-extra_practice-11-w1-objects-and-names", + "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "item:exam-midterm_2023-12-w1-functions-and-imports", + "item:exam-midterm_2023-4-w1-objects-and-names", + "item:exam-midterm_2024-16-w1-functions-and-imports", + "item:exam-midterm_2024-4-w1-objects-and-names", + "item:exam-midterm_2024-6-w1-objects-and-names", + "item:exam-trial_midterm-1-w1-objects-and-names", + "item:exam-trial_midterm-11-w1-objects-and-names", + "item:exam-trial_midterm-12-w1-objects-and-names", + "item:exam-trial_midterm-14-w1-objects-and-names", + "item:exam-trial_midterm-15-w1-objects-and-names", + "item:exam-trial_midterm-16-w1-objects-and-names", + "item:exam-trial_midterm-18-w1-objects-and-names", + "item:exam-trial_midterm-20-w1-objects-and-names", + "item:exam-trial_midterm-21-w1-objects-and-names", + "item:exam-trial_midterm-22-w1-objects-and-names", + "item:exam-trial_midterm-24-w1-objects-and-names", + "item:exam-trial_midterm-3-w1-objects-and-names", + "item:exam-trial_midterm-4-w1-objects-and-names", + "item:exam-trial_midterm-7-w1-objects-and-names", + "item:exam-trial_midterm-9-w1-objects-and-names", + "item:kp-1-d1", + "item:kp-1-d2", + "item:kp-2-d1", + "item:kp-2-d2", + "item:kp-3-d1", + "item:kp-3-d2", + "item:kp-4-d1", + "item:kp-6-d1", + "item:kp-6-d2", + "item:kp-7-d1", + "item:kp-manual-aliasing-copy-d1", + "item:ks-0153de2f70" + ] + }, + { + "week": 2, + "top1_unique_snippets": 22, + "top3_unique_snippets": 31, + "minimal_set_unique_snippets": 28, + "minimal_set_unused_snippets": 74, + "unused_snippet_ids": [ + "item:cs-3e39a2f12f", + "item:cs-curated-hw-conditions-first-match-wins", + "item:cs-curated-hw-dict-delete-shared-keys", + "item:cs-curated-hw-dict-digit-frequency", + "item:cs-curated-hw-dict-project-values-sorted-keys", + "item:cs-curated-hw-loops-enumerate-mark-max", + "item:cs-curated-hw-loops-market-clearing", + "item:cs-curated-hw-loops-nested-pairwise-dict", + "item:cs-curated-hw-loops-zip-filter-pairs", + "item:cs-fc8bdeb969", + "item:exam-Test Exam 07-06-22-4-w2-conditions", + "item:exam-extra_practice-12-w2-dictionaries-and-mappings", + "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "item:exam-extra_practice-8-w2-dictionaries-and-mappings", + "item:exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "item:exam-midterm_2023-1-w2-conditions", + "item:exam-midterm_2023-15-w2-lists-and-sets", + "item:exam-midterm_2023-2-w2-loops", + "item:exam-midterm_2023-5-w2-dictionaries-and-mappings", + "item:exam-midterm_2023-6-w2-dictionaries-and-mappings", + "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item:exam-midterm_2023-8-w2-dictionaries-and-mappings", + "item:exam-midterm_2024-10-w2-dictionaries-and-mappings", + "item:exam-midterm_2024-11-w2-dictionaries-and-mappings", + "item:exam-midterm_2024-12-w2-dictionaries-and-mappings", + "item:exam-midterm_2024-17-w2-loops", + "item:exam-midterm_2024-20-w2-loops", + "item:exam-midterm_2024-21-w2-loops", + "item:exam-midterm_2024-22-w2-lists-and-sets", + "item:exam-midterm_2024-23-w2-lists-and-sets", + "item:exam-midterm_2024-24-w2-lists-and-sets", + "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "item:exam-midterm_2024-8-w2-dictionaries-and-mappings", + "item:exam-midterm_2024-9-w2-loops", + "item:exam-trial_midterm-13-w2-conditions", + "item:exam-trial_midterm-2-w2-dictionaries-and-mappings", + "item:exam-trial_midterm-23-w2-dictionaries-and-mappings", + "item:exam-trial_midterm-5-w2-loops", + "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item:kp-1-d3", + "item:kp-1-d4", + "item:kp-2-d3", + "item:kp-iteration-traps-d1", + "item:kp-manual-break-continue", + "item:kp-manual-enumerate", + "item:kp-manual-enumerate-d1", + "item:kp-manual-loop-core", + "item:kp-manual-loop-core-d1", + "item:kp-manual-precedence", + "item:kp-manual-ternary" + ] + }, + { + "week": 3, + "top1_unique_snippets": 16, + "top3_unique_snippets": 25, + "minimal_set_unique_snippets": 22, + "minimal_set_unused_snippets": 43, + "unused_snippet_ids": [ + "item:cs-curated-hw-hof-nested-helper-hhi", + "item:exam-Resit 22/23-2-w3-scope", + "item:exam-Resit 22/23-3-w3-return-behavior", + "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item:exam-extra_practice-10-w3-higher-order-patterns", + "item:exam-extra_practice-7-w3-return-behavior", + "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "item:exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "item:exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "item:exam-midterm_2023-11-w3-higher-order-patterns", + "item:exam-midterm_2023-3-w3-scope", + "item:exam-midterm_2024-13-w3-arguments", + "item:exam-midterm_2024-14-w3-arguments", + "item:exam-midterm_2024-19-w3-higher-order-patterns", + "item:exam-midterm_2024-5-w3-scope", + "item:exam-trial-final-exam-py22-2-w3-scope", + "item:exam-trial_midterm-17-w3-higher-order-patterns", + "item:kp-manual-args-kwargs-return-d1", + "item:kp-manual-mutating-methods-none-d1", + "item:kp-manual-scope-global", + "item:kp-manual-scope-local", + "item:kp-manual-scope-return-outside", + "item:kp-manual-scope-unbound", + "item:ks-14515a5856", + "item:ks-40fee04740", + "item:ks-994a4083e3", + "item:ks-d1a2d7739d", + "item:ks-d26b85265c", + "item:ks-db93da9e3e", + "item:ks-e09d7f145b", + "item:ks-f069ee6a0b", + "item:ks-f5d65c7e89", + "item:manual-call-vs-index", + "item:manual-global", + "item:manual-list-of-dicts-loop", + "item:manual-string-return-shape", + "item:manual-unboundlocal", + "subtopic:w3-arguments:w3-arguments-core", + "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "subtopic:w3-return-behavior:w3-return-behavior-core", + "subtopic:w3-scope:w3-scope-core" + ] + }, + { + "week": 4, + "top1_unique_snippets": 5, + "top3_unique_snippets": 10, + "minimal_set_unique_snippets": 6, + "minimal_set_unused_snippets": 41, + "unused_snippet_ids": [ + "item:cs-0d319e4faf", + "item:cs-14245b8c1f", + "item:cs-30e53467b8", + "item:cs-e7bc165499", + "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "item:kp-5-d1", + "item:kp-8-d1", + "item:kp-9-d1", + "item:kp-manual-init-defaults-d1", + "item:kp-manual-init-defaults-d2", + "item:kp-manual-oop-compare-d1", + "item:kp-manual-self-attr-d1", + "item:kp-manual-string-method-results-d1", + "item:ks-2c73fabc68", + "item:ks-309158a68c", + "item:ks-40d373c410", + "item:ks-45aead894c", + "item:ks-5198d93ec1", + "item:ks-5cbba26b09", + "item:ks-72dda5450c", + "item:ks-9e278d1ee6", + "item:ks-acb7f400b2", + "item:ks-b734a22f46", + "item:ks-bdea67862f", + "item:ks-cdb152720e", + "item:ks-e4dc502d3e", + "item:ks-ea5a4acb43", + "item:ks-f80f1bf556", + "item:manual-find-vs-index", + "item:manual-init-default", + "item:manual-method-call", + "item:manual-self", + "item:manual-string-escapes", + "item:manual-string-immutability", + "subtopic:w4-error-handling:w4-error-handling-core", + "subtopic:w4-string-formatting:w4-string-formatting-core", + "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core" + ] + }, + { + "week": 5, + "top1_unique_snippets": 6, + "top3_unique_snippets": 8, + "minimal_set_unique_snippets": 8, + "minimal_set_unused_snippets": 47, + "unused_snippet_ids": [ + "item:cs-2e178eda82", + "item:cs-3d987070d4", + "item:cs-49cf15967e", + "item:cs-82ef14b9d5", + "item:cs-8bae99d6de", + "item:cs-8ec741987c", + "item:cs-b069af91f4", + "item:cs-b3e0b57d7a", + "item:cs-c4c296595e", + "item:cs-cdfd529b3d", + "item:cs-e6b6bd65f0", + "item:kp-5-d2", + "item:kp-manual-df-constructor", + "item:kp-manual-drop-missing-d1", + "item:kp-manual-drop-missing-d2", + "item:kp-manual-filter-aggregate-d1", + "item:kp-manual-filter-aggregate-d2", + "item:kp-manual-pandas-two-axis", + "item:kp-manual-pandas-two-axis-d1", + "item:kp-manual-series-default-index", + "item:kp-manual-series-vs-df", + "item:kp-manual-series-vs-df-d1", + "item:ks-0114a2cff0", + "item:ks-052ed25923", + "item:ks-0d2d15f8d2", + "item:ks-115ab52188", + "item:ks-17e621a20d", + "item:ks-18a9645168", + "item:ks-21496ff1cd", + "item:ks-2bed6c308f", + "item:ks-305a41a33e", + "item:ks-57ff66f9f1", + "item:ks-591dd1aa33", + "item:ks-75cf35c8b4", + "item:ks-99fe849762", + "item:ks-9a5d2c05fb", + "item:ks-dfc064979d", + "item:ks-f1be187b50", + "item:ks-f550a3ffc7", + "item:ks-f8eec928e1", + "item:manual-df-constructor", + "item:manual-series-index", + "item:manual-series-vs-dataframe", + "subtopic:w5-combining-data:w5-combining-data-core", + "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "subtopic:w5-pandas-core-structures:w5-pandas-core-structures-core", + "subtopic:w5-working-with-values:w5-working-with-values-core" + ] + }, + { + "week": 6, + "top1_unique_snippets": 3, + "top3_unique_snippets": 5, + "minimal_set_unique_snippets": 4, + "minimal_set_unused_snippets": 32, + "unused_snippet_ids": [ + "item:cs-905c77e1f3", + "item:exam-intro_python_sample_final_24_25-12-w2-conditions", + "item:kp-manual-comprehension-syntax-d1", + "item:kp-manual-datetime-day-of-year", + "item:kp-manual-datetime-delta", + "item:kp-manual-datetime-format", + "item:kp-manual-datetime-format-codes", + "item:kp-manual-datetime-format-codes-d1", + "item:kp-manual-datetime-iso", + "item:kp-manual-datetime-now", + "item:kp-manual-datetime-objects-vs-strings", + "item:kp-manual-datetime-objects-vs-strings-d1", + "item:kp-manual-datetime-replace", + "item:ks-0a4fcae36d", + "item:ks-0e5c8b8b42", + "item:ks-169cc25be1", + "item:ks-1bc815f6d1", + "item:ks-3e04c4d5e8", + "item:ks-662456da41", + "item:ks-72c58bb6b2", + "item:ks-86cd7ede1c", + "item:ks-900b394f8e", + "item:ks-b9d93f2bc1", + "item:ks-cacc4fbc21", + "item:ks-cd030b9520", + "item:ks-dd2965ef50", + "item:ks-e643ee5e77", + "item:manual-day-of-year", + "item:manual-strftime-vs-strptime", + "item:manual-timedelta-attrs", + "subtopic:w6-comprehensions:w6-comprehensions-core", + "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core" + ] + } + ], + "insights": [ + "Week 2 currently has the broadest minimal-set footprint with 28 unique snippets." + ], + "repeated_near_identical_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "count": 5 + }, + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "count": 4 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "count": 4 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "count": 4 + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "count": 3 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "count": 3 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "count": 3 + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "count": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "count": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "count": 3 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "count": 3 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "count": 2 + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "count": 2 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "count": 2 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "count": 2 + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "count": 2 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "count": 2 + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "count": 2 + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "count": 2 + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "count": 2 + }, + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "count": 2 + }, + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "count": 2 + }, + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "count": 2 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "count": 2 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "count": 2 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "count": 2 + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "count": 2 + }, + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "count": 2 + } + ], + "comparison": { + "certain": { + "current": 61, + "baseline": 88, + "delta": -27 + }, + "insufficient": { + "current": 71, + "baseline": 40, + "delta": 31 + }, + "partial": { + "current": 36, + "baseline": 40, + "delta": -4 + } + } +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/analytics/round2.md b/data/vision_exam_pipeline/analytics/round2.md new file mode 100644 index 0000000..1dbda6f --- /dev/null +++ b/data/vision_exam_pipeline/analytics/round2.md @@ -0,0 +1,22 @@ +# Ranking Analytics (round2) + +- Total evaluations: `168` +- Completed evaluations: `168` +- Status counts: `{"completed": 168}` +- Answerability counts: `{"certain": 61, "insufficient": 71, "partial": 36}` +- Repeated near-identical past-exam pieces: `42` + +## Week Summary + +| Week | Top 1 unique | Top 3 unique | Minimal-set unique | Minimal-set unused | +|---|---:|---:|---:|---:| +| 1 | 10 | 16 | 17 | 73 | +| 2 | 22 | 31 | 28 | 74 | +| 3 | 16 | 25 | 22 | 43 | +| 4 | 5 | 10 | 6 | 41 | +| 5 | 6 | 8 | 8 | 47 | +| 6 | 3 | 5 | 4 | 32 | + +## Insights + +- Week 2 currently has the broadest minimal-set footprint with 28 unique snippets. diff --git a/data/vision_exam_pipeline/evaluations/round2.json b/data/vision_exam_pipeline/evaluations/round2.json new file mode 100644 index 0000000..d0128e9 --- /dev/null +++ b/data/vision_exam_pipeline/evaluations/round2.json @@ -0,0 +1,61345 @@ +{ + "schema_version": "1.1", + "generated_at": "2026-03-24T10:43:09Z", + "round": "round2", + "question_bank_path": "data/vision_exam_pipeline/exam_question_bank.json", + "selectable_items_path": "data/vision_exam_pipeline/selectable_items_snapshot.json", + "questions": [ + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q01", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q01", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "Take a look at the following class definition.\n\nclass Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nGiven the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\nWhy?", + "options": { + "a": "The first argument (my_flight) should not have been passed to the set_date method in Code line 2.", + "b": "The capacity of the flight is not specified as an argument in Code line 1.", + "c": "The argument self is missing in Code line 1.", + "d": "The date string passed as an argument in Code line 2 represents an invalid date." + }, + "correct": "a", + "explanation": "set_date is an instance method, so Python passes self automatically. Passing my_flight explicitly adds an extra argument and causes the error.", + "code_context": "class Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\")\nmy_flight.set_date(my_flight, \"29-02-2022\")" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "kp-4", + "rationale": "Contains both a Key Point and an AI Example that explicitly use the 'set_date' method name to explain that passing the object explicitly results in 'one argument too many'." + }, + "top_three_snippets": [ + { + "item_id": "kp-4", + "rationale": "Contains both a Key Point and an AI Example that explicitly use the 'set_date' method name to explain that passing the object explicitly results in 'one argument too many'." + }, + { + "item_id": "manual-method-call", + "rationale": "Provides a direct, plain-English explanation of why calling a method with the object as the first argument causes a 'too many arguments' error." + }, + { + "item_id": "manual-self", + "rationale": "Explains the purpose of the 'self' parameter, which helps the student understand what Python is trying to pass automatically." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "kp-4", + "rationale": "The Key Point (kp-4) is the most efficient explanation available as it matches the question's method name and logic perfectly." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "This piece contains the exact class definition, code lines, and error scenario described in the question." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "Contains both a Key Point and an AI Example that explicitly use the 'set_date' method name to explain that passing the object explicitly results in 'one argument too many'.", + "critical_piece_ids": [ + "kp-4", + "ai-example-6" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:manual-method-call", + "rationale": "Provides a direct, plain-English explanation of why calling a method with the object as the first argument causes a 'too many arguments' error.", + "critical_piece_ids": [ + "manual-method-call" + ] + }, + { + "snippet_id": "item:manual-self", + "rationale": "Explains the purpose of the 'self' parameter, which helps the student understand what Python is trying to pass automatically.", + "critical_piece_ids": [ + "manual-self" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "The Key Point (kp-4) is the most efficient explanation available as it matches the question's method name and logic perfectly.", + "needed_piece_ids": [ + "kp-4" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets explicitly address the specific error of passing 'self' manually. Key Point 4 even uses the exact method name 'set_date' as an example of what NOT to do.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent. No concepts are missing.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T08:28:28Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:manual-self", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-self", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Why is `self` the first parameter of an instance method?\n`self` is the current object, so the method can read and update that object's attributes.\nclass Flight:\n def set_date(self, date):\n self.date = date" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:ks-06b21ad349", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ks-06b21ad349", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Class Definition and __init__\nA class is a blueprint. The __init__ method is the constructor called automatically when a new object is created to initialize attributes.\nDefining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color" + } + ] + }, + { + "snippet_id": "item:ks-9e278d1ee6", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ks-9e278d1ee6", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "The self Parameter\nIn class methods, 'self' refers to the specific instance of the object. It must be the first parameter of any instance method.\nUsing self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f" + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` is passed automatically in method calls\nclass Clock:\n def set_hour(self, hour):\n self.hour = hour\n\nc = Clock()\nc.set_hour(9)\n# c.set_hour(c, 9) # wrong: passes one argument too many\nWriting `obj.method(x)` already passes `self` for you. Inside the method, store " + }, + { + "item_id": "kp-4", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Method calls pass `self` automatically: `obj.set_date(x)` is correct; `obj.set_date(obj, x)` passes one argument too many." + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`." + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` refers to the current instance, so instance methods read and write data through `self.attr`." + }, + { + "item_id": "kp-manual-init-defaults", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Constructor defaults can make arguments optional, but mutable per-instance state should start from `None` and be created inside `__init__`." + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + } + ] + }, + { + "snippet_id": "item:manual-method-call", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-method-call", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Why does `obj.set_date(obj, x)` pass too many arguments?\nWhen you call a method on an object, Python passes the object as `self` automatically. Writing it again adds one argument too many.\nobj.set_date(x) # correct\nobj.set_date(obj, x) # too many args" + } + ] + }, + { + "snippet_id": "item:cs-0d319e4faf", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "cs-0d319e4faf", + "item_type": "source_notebook", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "class Rectangle:\nclass Rectangle:\n total_size = 0\n def __init__(self, length, width=1):\n self.length = length\n self.width = width\n Rectangle.total_size += self.length * self.width\n print(f'{self.length} by {self.width} created, {Rectangle.total_s" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:ks-5cbba26b09", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ks-5cbba26b09", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Class vs Instance Attributes\nInstance attributes (self.x) are unique to each object. Class attributes are defined outside methods and shared by all instances of the class.\nShared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q02", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q02", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "You have the following definition for a Book class.\n\nclass Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)\n\nSuppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book. The compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?", + "options": { + "a": "def compare(self, other):\n avg_better = self.average_score() > other.average_score()\n no_fewer_reviews = self.num_reviews() >= other.num_reviews()\n if avg_better and no_fewer_reviews:\n return self.title\n elif not avg_better:\n return other.title\n else:\n return None", + "b": "def compare(self, other):\n for first, second in [(self, other), (other, self)]:\n avg_better = first.average_score() > second.average_score()\n no_fewer_reviews = first.num_reviews() >= second.num_reviews()\n if avg_better and no_fewer_reviews:\n return first.title\n return None", + "c": "Both methods above compare the book objects as intended.", + "d": "Neither of the two methods above compare the book objects as intended." + }, + "correct": "b", + "explanation": "B checks whether either book is better than the other and returns that title, otherwise it returns None. A can incorrectly return the other book even when neither book is better.", + "code_context": "class Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-compare-none-case", + "rationale": "This family provides the conceptual framework for object comparison, specifically handling the 'None' fallback when neither object wins and tracing state through method calls." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-compare-none-case", + "rationale": "This family provides the conceptual framework for object comparison, specifically handling the 'None' fallback when neither object wins and tracing state through method calls." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Provides the base Book class definition used in the question, helping the student understand the context of existing methods like num_reviews and average_score." + }, + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Explains the syntax of method calls and the role of 'self', which is crucial for evaluating the method definitions in the options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-compare-none-case", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This piece contains the exact text and logic for the 'Book' class 'compare' method question found in the prompt." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "This family provides the conceptual framework for object comparison, specifically handling the 'None' fallback when neither object wins and tracing state through method calls.", + "critical_piece_ids": [ + "manual-oop-compare-none-case", + "kp-manual-oop-compare", + "manual-oop-state-compare" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Provides the base Book class definition used in the question, helping the student understand the context of existing methods like num_reviews and average_score.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Explains the syntax of method calls and the role of 'self', which is crucial for evaluating the method definitions in the options.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "", + "needed_piece_ids": [ + "manual-oop-compare-none-case", + "kp-manual-oop-compare" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The general snippets explicitly teach the concept of returning 'None' when neither object wins (the core differentiator between A and B). Additionally, the exact question is present in the past exam items.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic of 'None' fallbacks is covered, the specific Pythonic pattern used in Option B (looping over tuple pairs to check symmetry) is not explicitly illustrated.", + "missing_concepts": [ + "Symmetric comparison using loop-over-pairs pattern" + ], + "proposed_fix": "Add an AI example showing how to check if 'either A or B wins' using a list of tuples to avoid repetitive logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add an AI example to 'subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core' showing: \n```python\ndef get_winner(self, other):\n for a, b in [(self, other), (other, self)]:\n if a.score > b.score:\n return a.name\n return None\n```", + "why_helpful": "This directly maps to the logic in Option B, which is a common but slightly advanced pattern for students to recognize.", + "why_maybe_unnecessary": "A student might still eliminate Option A based purely on the 'None' fallback rule already present.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T08:28:52Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-oop-state-compare", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.sc" + }, + { + "item_id": "manual-oop-compare-none-case", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Return `None` when neither object clearly wins\nclass Book:\n def __init__(self, title, scores):\n self.title = title\n self.scores = scores\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def winner_against(self, other):\n if se" + }, + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` is passed automatically in method calls\nclass Clock:\n def set_hour(self, hour):\n self.hour = hour\n\nc = Clock()\nc.set_hour(9)\n# c.set_hour(c, 9) # wrong: passes one argument too many\nWriting `obj.method(x)` already passes `self` for you. Inside the method, store " + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + }, + { + "item_id": "manual-oop-init-defaults", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state " + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q03", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q03", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?", + "options": { + "a": "def get_tld(url):\n url_1 = url.split(\".\")[-1]\n return url_1.split(\"/\")[0]", + "b": "def get_tld(url):\n url_1 = url.split(\"//\")[1]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]", + "c": "def get_tld(url):\n return url.split(\"//\")[1].split(\"/\")[0].split(\".\")[-1]", + "d": "def get_tld(url):\n url_1 = url[url.find(\"www\") + 2:]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]" + }, + "correct": "a", + "explanation": "A splits on the last dot first, which leaves the page extension rather than the domain. The other options isolate the host name first and then extract the final dot-separated part.", + "code_context": "def get_tld(url):\n # Extract the top-level domain from a URL string" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about URLs, this is the only other snippet that mentions processing a string with specific characters ('-') to format an output, which is conceptually closest to parsing a URL string." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about URLs, this is the only other snippet that mentions processing a string with specific characters ('-') to format an output, which is conceptually closest to parsing a URL string." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Shows a function taking two strings as inputs, which helps a novice understand the basic structure of the functions in the options." + }, + { + "item_id": "aiq-4", + "rationale": "Provides general context on return behavior, which is useful for evaluating what the functions ultimately 'return'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Closest thematic match to string parsing." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Context for string inputs in functions." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This snippet contains the exact same question, including the URL examples and code options." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about URLs, this is the only other snippet that mentions processing a string with specific characters ('-') to format an output, which is conceptually closest to parsing a URL string.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Shows a function taking two strings as inputs, which helps a novice understand the basic structure of the functions in the options.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Provides general context on return behavior, which is useful for evaluating what the functions ultimately 'return'.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Closest thematic match to string parsing.", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Context for string inputs in functions.", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of the identical past exam question makes the answer certain. However, without that specific item, the rest of the library is insufficient as it contains no explanation of .split(), .find(), or negative indexing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The library is missing explicit definitions for the string methods used in the options (split, find) and the indexing behavior ([-1]).", + "missing_concepts": [ + "str.split() and indexing the resulting list", + "str.find() behavior", + "Negative indexing ([-1])", + "String slicing ([start:])" + ], + "proposed_fix": "Add a 'String Manipulation' Key Point snippet that explains how .split() creates a list and how to access elements from it, as well as how .find() and slicing work together." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new Key Point: 'String Methods for Parsing'. Content: '1. .split(\".\") breaks a string into a list at every dot. 2. [-1] gets the last item in a list or string. 3. .find(\"sub\") returns the starting index of a substring. 4. [start:] slices from an index to the end.'", + "why_helpful": "This would allow a student to solve the problem logically rather than relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "If the goal is only to pass by memorizing past exams, the identical snippet is sufficient.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:12:06Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q04", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q04", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "def is_anagram(word_1, word_2):\n return sorted(list(word_1.replace(\" \", \"\").lower())) == sorted(list(word_2.replace(\" \", \"\").lower()))", + "b": "def is_anagram(word_1, word_2):\n return word_1.replace(\" \", \"\").lower().sort() == word_2.replace(\" \", \"\").lower().sort()", + "c": "def is_anagram(word_1, word_2):\n return list(word_1.replace(\" \", \"\").lower()).sort() == list(word_2.replace(\" \", \"\").lower())", + "d": "def is_anagram(word_1, word_2):\n return sorted(list(word_1)).replace(\" \", \"\").lower() == sorted(list(word_2)).replace(\" \", \"\").lower()" + }, + "correct": "a", + "explanation": "A removes spaces, lowercases both strings, and compares the sorted letters. The other options misuse sort() or apply string operations to list objects in the wrong order.", + "code_context": "def is_anagram(word_1, word_2):\n # Compare the same letters in normalized, sorted form" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value)." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value)." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a basic context for working with lists of strings and checking conditions, though it lacks specific method details." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This item is an exact match for the current exam question text regarding is_anagram." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "This item is an exact match for the current exam question text regarding is_anagram." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value).", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a basic context for working with lists of strings and checking conditions, though it lacks specific method details.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the direct past-exam matches, the available snippets do not explain string methods (.replace, .lower) or the return value of .sort(). A zero-knowledge student would not know that .sort() returns None, making options B/C look viable, nor would they know the order of operations for list vs string methods.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to provide the semantic details of string manipulation and the specific behavior of sorting functions vs methods.", + "missing_concepts": [ + "String methods: .replace() and .lower() (syntax and return type)", + "The difference between the sorted() function (returns new list) and the .sort() method (returns None)", + "Method chaining order: applying string methods to the result of list() will fail" + ], + "proposed_fix": "Add a reference snippet for 'Common String & List Operations' that explicitly contrasts sorted(L) with L.sort() and lists common string methods like .replace() and .lower()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: 'Python String & Sorting Basics'. Content: 'str.replace(\" \", \"\")' removes spaces; 'str.lower()' normalizes case. 'sorted(my_list)' returns a new sorted list (use for comparisons). 'my_list.sort()' returns None (do not use in comparisons).", + "why_helpful": "Directly addresses the distractors in the question by explaining why .sort() in an equality check fails.", + "why_maybe_unnecessary": "Could be considered basic language knowledge, but required for the 'zero-knowledge' target persona.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:13:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q05", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q05", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "Pandas", + "question": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "s.map((s - s.mean())**2)", + "b": "(s - s.mean())**2", + "c": "s.map(lambda x: (x - s.mean())**2)", + "d": "(s - s.mean()).map(lambda x: x**2)" + }, + "correct": "a", + "explanation": "A is not the right way to apply the squared-difference expression to each element of the Series. B, C, and D all produce the desired squared differences.", + "code_context": "# s is a pandas Series of floats" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that the .map() method is used to apply a function, which helps identify that option (a) is incorrect because it tries to pass a Series result directly to map." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that the .map() method is used to apply a function, which helps identify that option (a) is incorrect because it tries to pass a Series result directly to map." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Introduces the concept of vectorized operations in Pandas, which explains why option (b) works." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows another example of creating a new column/Series using simple arithmetic between existing columns, reinforcing vectorization." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This is the exact same question from a previous exam." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that the .map() method is used to apply a function, which helps identify that option (a) is incorrect because it tries to pass a Series result directly to map.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Introduces the concept of vectorized operations in Pandas, which explains why option (b) works.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows another example of creating a new column/Series using simple arithmetic between existing columns, reinforcing vectorization.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam piece provides the answer directly. Even without it, the explanation that .map() requires a function (from snippet item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals) allows a student to deduce that passing a Series calculation inside .map() is the likely error.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the map() snippet mentions it takes a function, it doesn't explicitly contrast this with vectorization or state that passing a Series to map() is a common mistake.", + "missing_concepts": [ + "Difference between vectorized operations and .map()", + "Explicit requirement of a callable for .map() versus element-wise math" + ], + "proposed_fix": "Add a conceptual snippet explaining that Pandas Series support element-wise math directly (vectorization) and that .map() specifically requires a function or dictionary as an argument." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Pandas Vectorization vs. Mapping: Use simple math operators (+, -, *, **, etc.) directly on a Series to apply that operation to every element (vectorized). Use .map(function) only when you need to apply a specific custom function to each element. Passing a Series calculation into .map() like s.map(s * 2) is invalid.", + "why_helpful": "It directly clarifies the 'trick' in the question where option A uses map incorrectly with a vectorized expression.", + "why_maybe_unnecessary": "The existing 'Applying a function' note in the map snippet might be enough for a smart student to infer the error.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:13:44Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q06", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q06", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-2", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the difference of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] - df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x - df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\"] - df.columns[\"B\"]", + "d": "df[\"C\"] = df.apply(df[\"A\"] - df[\"B\"])" + }, + "correct": "a", + "explanation": "Subtracting one numeric Series from another directly creates the elementwise difference needed for column C.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Excluding near-identical items, this is the most helpful as it discusses the 'square of the difference between the corresponding element' in a Series, reinforcing the concept of element-wise operations." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Excluding near-identical items, this is the most helpful as it discusses the 'square of the difference between the corresponding element' in a Series, reinforcing the concept of element-wise operations." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame with columns A, B, and C, helping a student with zero knowledge visualize the data structure mentioned in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This question is structurally identical to the target question (DataFrame 'df', columns 'A', 'B', 'C'), only asking for 'sum' instead of 'difference'." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Another near-identical past question that explicitly mentions 'Vectorized addition' in its explanation, which directly translates to vectorized subtraction." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Excluding near-identical items, this is the most helpful as it discusses the 'square of the difference between the corresponding element' in a Series, reinforcing the concept of element-wise operations.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame with columns A, B, and C, helping a student with zero knowledge visualize the data structure mentioned in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The student can answer correctly via pattern matching using the near-identical 'sum' question, combined with the conceptual hint of 'vectorized' operations mentioned in its explanation.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While answerable through pattern matching of past exams, there is a lack of a general-purpose snippet explaining Pandas arithmetic syntax and column creation.", + "missing_concepts": [ + "Pandas vectorized arithmetic", + "Column assignment/creation syntax (df['new'] = ...)" + ], + "proposed_fix": "Add a conceptual key point snippet explaining that mathematical operators (+, -, *, /) work element-wise between Pandas Series and show the syntax for creating new columns." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point: 'Pandas Vectorized Operations: You can perform arithmetic directly on columns (e.g., df[\"C\"] = df[\"A\"] - df[\"B\"]). This performs the operation for every row automatically.'", + "why_helpful": "It moves the student from pattern matching past exams to understanding the underlying concept of vectorized operations.", + "why_maybe_unnecessary": "The near-identical exam pieces already make the question answerable for the exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:14:36Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q07", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q07", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-3", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 8.7 4.6 9.5 7.0\n2 7.3 1.5 6.3 7.1\n3 4.3 9.0 2.9 3.3\n4 4.8 2.5 5.1 3.0\n5 1.6 1.4 6.7 3.5\n6 2.4 3.7 7.6 1.3\n\nSuppose that you'd like to create a new Series that only contains those elements of column \"D\" of df that are smaller than 5.0. So the Series should look like this, when printed:\n\n3 3.3\n4 3.0\n5 3.5\n6 1.3\nName: D, dtype: float64\n\nWhich of the following code lines will not achieve what you want?", + "options": { + "a": "df.loc[2:6, df.columns[-1]]", + "b": "df.loc[df[\"D\"] < 5, \"D\"]", + "c": "df.loc[3:6, \"D\"]", + "d": "df.iloc[2:6, 3]" + }, + "correct": "a", + "explanation": "Option A slices rows 2 through 6 from the last column but does not filter out values that are 5.0 or larger, so it includes values that should not be in the result.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic DataFrame column access and vectorized operations, helping the student understand DataFrame syntax." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This piece uses the exact same DataFrame structure and a nearly identical problem statement about selecting data from column 'D'." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic DataFrame column access and vectorized operations, helping the student understand DataFrame syntax.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets show examples of pandas syntax, they do not explicitly define the rules for .loc (label-based, inclusive) vs .iloc (integer-based, exclusive) or how negative indexing works with columns, which are critical for distinguishing option A from the others.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide examples but lack a conceptual summary of pandas selection methods (.loc vs .iloc) and boolean indexing logic.", + "missing_concepts": [ + "Label-based vs Integer-based indexing (.loc vs .iloc)", + "Boolean indexing/filtering in Pandas", + "Slicing behavior (inclusive vs exclusive) in .loc and .iloc", + "Negative column indexing using df.columns[-1]" + ], + "proposed_fix": "Add a summary snippet for 'Pandas Inspecting and Selecting Data' that explicitly compares .loc and .iloc with examples of slicing and boolean masks." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Pandas Selection Cheat Sheet' item. Include: 1) .loc[row_label, col_label] is inclusive. 2) .iloc[row_pos, col_pos] is exclusive at the end. 3) df[df['col'] < val] filters rows. 4) df.columns[-1] refers to the last column name.", + "why_helpful": "It would allow a student to systematically check each option (a, b, c, d) against the rules rather than relying on pattern matching with other exam questions.", + "why_maybe_unnecessary": "The near-identical exam piece already provides the answer, but doesn't help with underlying understanding if the question varies slightly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:14:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q08", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q08", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-4", + "question": "You have two DataFrames: df1 and df2. They look like this when printed:\n\nprint(df1)\n\n Age Height Female City Language\n0 23 167 True Berlin German\n1 36 175 True Frankfurt German\n2 17 182 False Antwerpen Dutch\n3 25 177 True Eindhoven Dutch\n4 36 178 False Lyon French\n5 52 185 False Basel German\n6 46 168 True Innsbruck German\n\nprint(df2)\n\n Age Height Female City Language\n5 52 185 False Basel German\n4 36 178 False Lyon French\n1 36 175 True Frankfurt German\n6 46 168 True Innsbruck German\n0 23 167 True Berlin German\n\nWhich of the following code segments could have created df2 from df1?", + "options": { + "a": "df1.loc[df1[\"Language\"].isin([\"French\", \"German\"])].sort_values(\"Height\", ascending=False)", + "b": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_values(\"Age\", ascending=False)", + "c": "df1.loc[~df1[\"Language\"].isin([\"Dutch\"]), [\"Age\", \"Height\", \"City\", \"Language\"]].sort_index(ascending=False)", + "d": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_index(axis=1)" + }, + "correct": "a", + "explanation": "Option A filters out the Dutch rows and then sorts the remaining rows by Height in descending order, matching df2 exactly.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides basic context on pandas DataFrame operations and column-based logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides basic context on pandas DataFrame operations and column-based logic.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The available snippets only mention 'Inspecting and Selecting Data' but do not provide the syntax or behavior for .isin(), .sort_values(), or .sort_index(). A student without prior knowledge would not be able to distinguish between the sorting and filtering methods used in the options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing critical documentation on pandas filtering (isin) and sorting (sort_values/sort_index).", + "missing_concepts": [ + "pandas.Series.isin()", + "pandas.DataFrame.sort_values()", + "pandas.DataFrame.sort_index()", + "Boolean indexing on string columns" + ], + "proposed_fix": "Add a dedicated snippet for 'Pandas Sorting and Filtering' that includes examples of selecting rows based on categories (isin) and reordering rows by column values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet family 'Pandas: Filtering and Sorting' with a piece demonstrating: 1. df[df['col'].isin(['val1', 'val2'])], 2. df.sort_values('col', ascending=False), and 3. df.sort_index().", + "why_helpful": "This directly covers the specific methods tested in this exam question, allowing a student to identify that Option A uses the correct filtering and sorting logic.", + "why_maybe_unnecessary": "If the student already knows basic pandas, they might guess based on English names, but it's not robust for a 'zero knowledge' use case.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:15:20Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q09", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q09", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-1", + "question": "You have a list of mountain peaks and their heights in meters, all formatted as \"[PEAK NAME]: [HEIGHT]m\". For example, a few elements of the list are:\n\"Denali: 6,190m\", \"Aconcagua: 6,961m\", \"Kilimanjaro: 5,895m\", ...\n\nAs you can see, the comma (\",\") is used as a thousand separator in the height. The list is called mountains.\n\nYou'd like to create a dictionary called peaks from the mountains list. The peak names would be the keys, and the corresponding integer values. Continuing the example above, a few key-value pairs of the peaks dictionary should be:\n\"Denali\": 6190, \"Aconcagua\": 6961, \"Kilimanjaro\": 5895, ...\n\nWhich of the following two code segments achieves what you want?", + "options": { + "a": "peaks = {peak.split(\":\")[0]: int(peak.split(\": \")[1][:-1].replace(\",\", \"\")) for peak in mountains}", + "b": "names = [peak.split(\":\")[0] for peak in mountains]\nheights = [int(peak.split(\": \")[1].replace(\",\", \"\").replace(\"m\", \"\")) for peak in mountains]\npeaks = dict(zip(names, heights))", + "c": "Both code segments above achieve the intended outcome.", + "d": "Neither of the two code segments above achieves the intended outcome." + }, + "correct": "c", + "explanation": "Both solutions strip off the trailing m, remove the thousands separator, convert the height to an integer, and pair each mountain name with its numeric height.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates creating a dictionary from two separate lists (names and values), which confirms the validity of the structural pattern used in Option B." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides a conceptual precedent for extracting specific substrings (like a TLD) from a larger formatted string, mirroring the task of parsing names and heights." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates creating a dictionary from two separate lists (names and values), which confirms the validity of the structural pattern used in Option B.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides a conceptual precedent for extracting specific substrings (like a TLD) from a larger formatted string, mirroring the task of parsing names and heights.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide strong structural evidence that both Code Segment A (dictionary comprehension) and Code Segment B (zip/dict) are valid Python patterns for creating dictionaries. However, a student with zero prior knowledge would still struggle to verify the 'string cleaning' logic (split, replace, slicing) as none of the snippets explicitly show these methods in action.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Structural dictionary patterns are well-covered, but the specific string manipulation methods required to 'clean' the data are missing.", + "missing_concepts": [ + "String .split() method", + "String .replace() method", + "String slicing syntax (e.g., [:-1])", + "The use of int() for converting numeric strings" + ], + "proposed_fix": "Add a reference snippet or past exam item that explicitly uses .split(), .replace(), and slicing to parse strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'String Cleaning' reference snippet: 'text.split(\": \")[1]' extracts data after a colon, 'text.replace(\",\", \"\")' removes characters, and 'text[:-1]' removes the last character (like 'm').", + "why_helpful": "This allows a zero-knowledge student to confirm that the complex-looking expressions inside the comprehensions actually perform the specific cleanup described in the question.", + "why_maybe_unnecessary": "The student might guess the meaning of .replace() or .split() based on common English definitions, but precise confirmation is better for 'certain' answerability.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:15:55Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q10", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q10", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-2", + "question": "You have a dictionary called grades, in which the keys are unique student ID's (as strings) and the corresponding values are each student's Python course grades (as floats).\n\nYou'd like to create another dictionary called grade_curve, in which the keys are the 18 possible Dutch course grades (1.0, 1.5, 2.0, ..., 10) as floats, and the corresponding (integer) values are the number of students in grades who have that particular grade.\n\nTake a look at the following code segment to create the grade_curve dictionary.\n\ndutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0,\n 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}\n\nDo you think this code segment will always work as intended? If not, then why not?", + "options": { + "a": "Yes, the code will always work as intended.", + "b": "The code will not work as intended if there are certain grades that no student has received. That will lead to an error in constructing the dictionary comprehension.", + "c": "The code will not work as intended, because the keys of the grades dictionary are not used in the list comprehension inside the sum function.", + "d": "The code will not work as intended, because including a list comprehension inside a dictionary comprehension will lead to a Python syntax error." + }, + "correct": "a", + "explanation": "The inner comparison list produces True and False values for every grade entry, and sum counts the matches, including zero when no student received that grade.", + "code_context": "dutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the syntax and validity of dictionary comprehensions, which helps rule out option (d)." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Provides another example of generating a dictionary from a sequence using logic in a comprehension." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question.", + "critical_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the syntax and validity of dictionary comprehensions, which helps rule out option (d).", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Provides another example of generating a dictionary from a sequence using logic in a comprehension.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets show that dictionary comprehensions are a standard and valid way to count items or transform lists into dictionaries. However, none explicitly explain that 'sum()' on a list of booleans converts True to 1 and False to 0, which is the specific mechanism used in the question's code.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets confirm that the syntax is valid (ruling out d) and that dictionary counting is a common pattern. However, the specific behavior of sum() with booleans and the fact that an empty match returns 0 rather than an error is not explicitly covered.", + "missing_concepts": [ + "sum() behavior with Boolean values (True=1, False=0)", + "Behavior of comprehensions when no items match a condition (returns 0 for sum of empty/false list)" + ], + "proposed_fix": "Add a snippet or detail explaining how Python handles boolean arithmetic and summing lists of comparison results." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining that in Python, True behaves like 1 and False like 0 when used in mathematical functions like sum(). Example: sum([True, False, True]) == 2.", + "why_helpful": "This is the core concept required to understand why the provided code segment 'always works' and doesn't produce an error when a grade has zero matches.", + "why_maybe_unnecessary": "Students might have learned that booleans are integers in an earlier lecture, but it is a common 'trick' question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:16:18Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q11", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q11", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-1", + "question": "What does the following code segment print to the screen?\n\nfrom datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "options": { + "a": "26-03-2020", + "b": "04-24-2020", + "c": "15-04-2020", + "d": "05-14-2020" + }, + "correct": "a", + "explanation": "The string is parsed as 5 April 2020 using month.day.year format, and subtracting 10 days yields 26 March 2020, which is then formatted as day-month-year.", + "code_context": "from datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-add-before-format", + "rationale": "This family contains an AI example ('manual-datetime-add-before-format') that follows the exact logical flow of the question: parse a string, perform arithmetic with timedelta, and format the result back into a string." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-add-before-format", + "rationale": "This family contains an AI example ('manual-datetime-add-before-format') that follows the exact logical flow of the question: parse a string, perform arithmetic with timedelta, and format the result back into a string." + }, + { + "item_id": "ks-755c23c4be", + "rationale": "Provides explicit definitions for %m (month) and %Y (year), which are crucial for the student to correctly identify that '04' is the month in the input string." + }, + { + "item_id": "cs-905c77e1f3", + "rationale": "Demonstrates strptime with various custom separators, helping the student understand how the format string ('%m.%d.%Y') maps to the input string ('04.05.2020')." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-add-before-format", + "rationale": "" + }, + { + "item_id": "ks-755c23c4be", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "rationale": "This family contains an AI example ('manual-datetime-add-before-format') that follows the exact logical flow of the question: parse a string, perform arithmetic with timedelta, and format the result back into a string.", + "critical_piece_ids": [ + "manual-datetime-add-before-format", + "manual-datetime-format" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-755c23c4be", + "rationale": "Provides explicit definitions for %m (month) and %Y (year), which are crucial for the student to correctly identify that '04' is the month in the input string.", + "critical_piece_ids": [ + "ks-755c23c4be" + ] + }, + { + "snippet_id": "item:cs-905c77e1f3", + "rationale": "Demonstrates strptime with various custom separators, helping the student understand how the format string ('%m.%d.%Y') maps to the input string ('04.05.2020').", + "critical_piece_ids": [ + "cs-905c77e1f3" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "rationale": "", + "needed_piece_ids": [ + "manual-datetime-add-before-format" + ] + }, + { + "snippet_id": "item:ks-755c23c4be", + "rationale": "", + "needed_piece_ids": [ + "ks-755c23c4be" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the 'Parse, do arithmetic, then format' AI example and the definition of format codes in the lecture snippet covers every step required to solve the question without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are highly effective, though %d (day) is only implicitly shown rather than explicitly defined.", + "missing_concepts": [ + "Explicit definition of the %d format code" + ], + "proposed_fix": "Enhance the lecture or AI snippet to include a concise table of the most common format codes (%d, %m, %Y, %H, %M)." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-755c23c4be", + "proposal": "Update the description of format codes to explicitly list %d as 'day of month (01-31)'.", + "why_helpful": "Reduces the need for the student to guess that %d stands for day, especially when the date '04.05' could be ambiguous (Month.Day vs Day.Month) if codes aren't known.", + "why_maybe_unnecessary": "The student can likely infer the meaning from the surrounding code and the options provided.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:16:47Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:ks-86cd7ede1c", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "ks-86cd7ede1c", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Timedelta and Date Arithmetic\nTimedelta objects represent durations. Subtracting two datetimes creates a timedelta; adding a timedelta to a datetime shifts the date.\nCalculating days difference\nfrom datetime import datetime, timedelta\ndiff = datetime(2024, 1, 1) - datetime(2023, " + } + ] + }, + { + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "manual-datetime-add-before-format", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Parse, do arithmetic, then format\nfrom datetime import datetime, timedelta\n\ndt = datetime.strptime('2024-05-20 14:30', '%Y-%m-%d %H:%M')\nupdated = dt + timedelta(days=2, minutes=15)\nprint(updated.strftime('%Y-%m-%d %H:%M'))\nThe safe order is parse -> work with the datetime object" + }, + { + "item_id": "manual-datetime-day-of-year", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Compute the day number within the year\nfrom datetime import datetime\n\ndef day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1\n\nprint(day_of_year(datetime(2024, 5, 20)))\nSubtract January 1st of the same year, then add 1 so January 1st becomes day 1." + }, + { + "item_id": "manual-datetime-delta", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Subtract datetimes to get a `timedelta`\nfrom datetime import datetime\n\nstart = datetime(2024, 1, 1)\nend = datetime(2024, 1, 4)\nprint((end - start).days)\nDatetime subtraction gives a `timedelta`, whose `.days` attribute is often what exam questions want.\n3" + }, + { + "item_id": "manual-datetime-replace", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "`.replace(...)` returns a new datetime\nfrom datetime import datetime\n\nd = datetime(2024, 5, 20)\nprint(d.replace(year=2026))\nprint(d)\nDatetime objects are immutable, so `.replace(...)` does not modify the original object in place.\n2026-05-20 00:00:00\n2024-05-20 00:00:00" + }, + { + "item_id": "manual-datetime-strftime-loop", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Do datetime math before `strftime` turns values into strings\nfrom datetime import datetime, timedelta\n\nday = datetime(2024, 1, 1)\nlabels = []\nfor _ in range(3):\n labels.append(day.strftime(\"%Y-%m-%d\"))\n day += timedelta(days=1)\nprint(labels)\nAfter `strftime`, the value is p" + }, + { + "item_id": "manual-datetime-format", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Format a datetime with `strftime`\nfrom datetime import datetime\n\ndt = datetime(2024, 5, 20, 14, 30)\nprint(dt.strftime('%Y-%m-%d %H:%M'))\nUse `strftime` when the exam asks for a formatted string such as year-month-day or hour-minute.\n2024-05-20 14:30" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:ks-755c23c4be", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "ks-755c23c4be", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "strftime: Date to String\nFormats a datetime object into a readable string using format codes (e.g., %Y for 4-digit year, %m for month).\nFormatting a date\nfrom datetime import datetime\nprint(datetime.now().strftime('%Y-%m-%d %H:%M'))" + } + ] + }, + { + "snippet_id": "item:cs-905c77e1f3", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "cs-905c77e1f3", + "item_type": "source_notebook", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "from datetime import datetime\nfrom datetime import datetime\nd = datetime.strptime(\"2024$05%20\",\"%Y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q12", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q12", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-2", + "question": "Suppose you have the following definition for a Meeting class, which records basic information about meetings in a calendar application.\n\nYou would like to add a method called lunch_meeting to this class, which returns a boolean value indicating whether there is any overlap between the official lunchtime (12:30 - 13:00) and the time of the meeting.\n\nFor example, if you construct a Meeting object as:\nmy_meeting = Meeting('Ask for salary raise', \"25-05-2022\", start_time='12:00', length=45)\nthen the method call:\nmy_meeting.lunch_meeting()\nshould return the boolean value True.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = lunch_start + timedelta(minutes=30)\n return self.start < lunch_end and self.end > lunch_start", + "b": "def lunch_meeting(self):\n return self.start < \"13:00\" and self.end > \"12:30\"", + "c": "def lunch_meeting(self):\n return start_time <= \"13:00\" and start_time + length > \"12:30\"", + "d": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = datetime(self.date.year, self.date.month, self.date.day, 13, 0)\n return self.start >= lunch_end or self.end <= lunch_start" + }, + "correct": "a", + "explanation": "Option A constructs the lunch interval on the same date and uses the standard interval-overlap check. The other options compare datetimes to strings, reference names that are not in scope, or use the non-overlap condition instead.", + "code_context": "from datetime import datetime, timedelta\n\nclass Meeting:\n def __init__(self, topic, date, start_time=\"09:00\", length=30):\n self.topic = topic\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day,\n int(start_time.split(':')[0]), int(start_time.split(':')[1]))\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining classes and initializing attributes, which helps the student understand the 'Meeting' class context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining classes and initializing attributes, which helps the student understand the 'Meeting' class context.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets mention the 'datetime' or 'timedelta' modules. A student with zero prior knowledge would not know how to construct a datetime object using 'datetime(year, month, day, hour, minute)', how to add time using 'timedelta', or how to compare datetime objects. The logic for interval overlap is also not explained.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provided focus on basic OOP and Pandas, completely missing the Week 8 'datetime' content required for this question.", + "missing_concepts": [ + "datetime module syntax (datetime constructor)", + "timedelta for time arithmetic", + "Datetime comparison operators (<, >)", + "General logic for checking overlapping time intervals" + ], + "proposed_fix": "Add a new snippet for the datetime module that explains how to create timestamps and add durations, specifically including the standard interval overlap logic: (start1 < end2 and end1 > start2)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Working with Datetimes'. Content: 'from datetime import datetime, timedelta'. Explain: 'datetime(year, month, day, hour, minute)' creates a point in time. 'timedelta(minutes=30)' represents a duration. Datetimes can be compared with < and >. Logic: Two intervals (start1, end1) and (start2, end2) overlap if 'start1 < end2 and end1 > start2'.", + "why_helpful": "This provides the specific library syntax and the mathematical logic needed to identify Option A as correct and others as incorrect.", + "why_maybe_unnecessary": "Only if the student is expected to already have these library details from a general Python reference, but the goal is to help those with 'almost zero' knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:17:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q13", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q13", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Basic logic 2", + "question": "Suppose you have a variable x which contains a list of tuples, as follows:\n\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nChoose the correct output for the following line of code.\n\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "options": { + "a": "True", + "b": "False", + "c": "NameError", + "d": "SyntaxError" + }, + "correct": "a", + "explanation": "The left-hand side is 2 * 3 = 6 and the right-hand side is 8 - 2 = 6, so the comparison evaluates to True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "While technically a different topic, this snippet provides the most explicit example of list/string indexing syntax `[1::2]` and implied indexing logic, which is the core concept needed if the direct exam matches were excluded." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "While technically a different topic, this snippet provides the most explicit example of list/string indexing syntax `[1::2]` and implied indexing logic, which is the core concept needed if the direct exam matches were excluded." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Shows list manipulation and the result of extraction/sorting, helping a student understand how Python handles collections." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Matches the exact variable `x = [(1, 2), (3, 4), (5, 6), (7, 8)]` and explains the evaluation of `2 * 3 == 6`." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Identical logic and explanation for a list of tuples named x, confirming the arithmetic result." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "While technically a different topic, this snippet provides the most explicit example of list/string indexing syntax `[1::2]` and implied indexing logic, which is the core concept needed if the direct exam matches were excluded.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Shows list manipulation and the result of extraction/sorting, helping a student understand how Python handles collections.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question (or a near-identical version) from a past exam, including a step-by-step breakdown of the indexing arithmetic (2 * 3 == 6 and 8 - 2 == 6).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets rely heavily on the student finding the 'past exam' match. If those weren't there, a student would need a clear guide on negative indexing (e.g., x[-1]) and nested indexing (e.g., x[0][1]).", + "missing_concepts": [ + "Negative indexing in lists", + "Multi-dimensional/nested indexing (accessing elements within tuples inside a list)" + ], + "proposed_fix": "Add a foundational snippet explaining that index -1 is the last item, -2 is second to last, and how x[0][1] traverses the first list item then the second tuple item." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Indexing Cheat Sheet. Content: x[0] is first, x[-1] is last. For x = [(a, b)], x[0][0] is 'a' and x[0][1] is 'b'.", + "why_helpful": "Provides the structural rules to solve the math manually without relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "The 'near identical' exam pieces already provide the answer for this specific problem instance.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:17:21Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q14", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q14", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Basic loop 2", + "question": "Which of the following code segments will print every even number between 0 and 20 (including 0 and 20) to the screen?", + "options": { + "a": "for i in range(0, 20):\n if i % 2 == 0:\n print(i)", + "b": "i = 0\nwhile i <= 20:\n if i % 2 == 0:\n print(i)\n i += 1", + "c": "for i in list(range(0, 20)):\n print(i if i % 2 == 0 else None)", + "d": "i = 0\nwhile i < 21:\n print(i)\n i += 1" + }, + "correct": "b", + "explanation": "Option B checks every integer from 0 through 20 inclusive and prints only the even ones. Option A never reaches 20, option C also prints None for odd numbers, and option D prints every number.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D)." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "While the code is not shown, the text confirms that 'sum_even_in_list' involves filtering for even integers, which reinforces the concept of searching for parity-checking logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D).", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "While the code is not shown, the text confirms that 'sum_even_in_list' involves filtering for even integers, which reinforces the concept of searching for parity-checking logic.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "No snippet explains the modulo operator (%) used to check for even numbers (i % 2 == 0). Furthermore, there is no explanation that range(0, 20) is exclusive of 20, which is the primary reason option A is incorrect.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets fail to define the two most critical mechanics for this question: the modulo operator for parity and the upper-bound behavior of the range() function.", + "missing_concepts": [ + "modulo operator (%)", + "range() upper bound exclusivity" + ], + "proposed_fix": "Add a foundational snippet from Week 2 (Loops) or Week 1 (Expressions) explaining that 'a % b' is the remainder and that 'range(start, stop)' stops before 'stop'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Loop and Math Basics' explaining: 1. 'range(0, 10)' produces numbers 0-9 (excludes 10). 2. 'x % 2 == 0' checks if a number is even.", + "why_helpful": "This would allow a student to eliminate distractors A and C (due to range behavior) and confirm B over D (due to even-number filtering).", + "why_maybe_unnecessary": "Basic math might be assumed, but range behavior is specific to Python and essential here.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:17:48Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q15", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q15", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Basic scope 2", + "question": "Choose the correct statement about the program below:", + "options": { + "a": "a is a global variable. b, c, d are local variables.", + "b": "a, b are global variables. c, d are local variables.", + "c": "a, b, c, d are global variables.", + "d": "a, c, d are global variables. b is a local variable." + }, + "correct": "a", + "explanation": "`a` is defined at module level, so it is global. `b` is local to `outer`, and `c` and `d` are local to `inner`.", + "code_context": "a = 1\ndef outer(b):\n b = 2\n def inner(c):\n d = 3\n return a + c + d\n return inner(4) + b" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "This lecture snippet provides the exact definitions needed: 'Local names' include parameter names and any assignment inside a function, while 'Global names' are defined outside any function. This maps perfectly to 'a' (outside), 'b' and 'c' (parameters), and 'd' (assignment)." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "This lecture snippet provides the exact definitions needed: 'Local names' include parameter names and any assignment inside a function, while 'Global names' are defined outside any function. This maps perfectly to 'a' (outside), 'b' and 'c' (parameters), and 'd' (assignment)." + }, + { + "item_id": "manual-local-name", + "rationale": "Explicitly confirms that parameter names (like 'b' and 'c' in the question) are local to the function body, which reinforces the primary rule." + }, + { + "item_id": "ks-f069ee6a0b", + "rationale": "Explains that functions can be defined inside other functions, which helps a student with no prior knowledge understand the nested 'outer/inner' structure shown in the code." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "manual-local-name", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "This lecture snippet provides the exact definitions needed: 'Local names' include parameter names and any assignment inside a function, while 'Global names' are defined outside any function. This maps perfectly to 'a' (outside), 'b' and 'c' (parameters), and 'd' (assignment).", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:manual-local-name", + "rationale": "Explicitly confirms that parameter names (like 'b' and 'c' in the question) are local to the function body, which reinforces the primary rule.", + "critical_piece_ids": [ + "manual-local-name" + ] + }, + { + "snippet_id": "item:ks-f069ee6a0b", + "rationale": "Explains that functions can be defined inside other functions, which helps a student with no prior knowledge understand the nested 'outer/inner' structure shown in the code.", + "critical_piece_ids": [ + "ks-f069ee6a0b" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:manual-local-name", + "rationale": "", + "needed_piece_ids": [ + "manual-local-name" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The definition in ks-2a6510492d is comprehensive. It allows a student to look at each variable in the code and classify it as global or local based on whether it is outside a function or inside as a parameter/assignment. The supporting snippets clarify the structure and parameters specifically.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover the classification logic completely.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:18:12Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-extra_practice-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modif" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:ks-00b2983ca8", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "ks-00b2983ca8", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Return statement\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.\nReturning a tuple (multiple values)\ndef po" + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:ks-f069ee6a0b", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "ks-f069ee6a0b", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Nested functions and function factories\nFunctions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).\nFunction factory\ndef function_factory(increment):\n " + } + ] + }, + { + "snippet_id": "item:manual-local-name", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "manual-local-name", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Why does `print(n1)` fail outside `def adder(n1, n2): ...`?\nParameter names are local to the function body, so they do not exist in the global scope after the call finishes.\ndef adder(n1, n2):\n return n1 + n2\n\nadder(1, 2)\nprint(n1)" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?\na\nb\nc\nd\nb\nThe global variable 'a' is accessible inside the inner function without error. The code evaluates to inner(5) * 3 = (1 + 5 + 4) * 3 = 30." + } + ] + }, + { + "snippet_id": "item:ks-d26b85265c", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "ks-d26b85265c", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Default arguments\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.\nDefault value\nde" + } + ] + }, + { + "snippet_id": "item:manual-unboundlocal", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "manual-unboundlocal", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Why can assigning to a name inside a function cause `UnboundLocalError`?\nIf a function assigns to a name anywhere in its body, Python treats that name as local throughout the function unless you declare it `global` or `nonlocal`.\nb = 1\n\ndef main(a):\n b = b\n return a" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q16", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q16", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-1", + "question": "You have to write a function called main, which takes a list of unique integers as an argument and returns a dictionary.\n\nThe output dictionary should consist of all key-value pairs for which the key is an element of the input list and the value is the next element of the input list. When there is no \"next element\" any more, leave the key-value pair out of the dictionary.\n\nFor example, if your function is called as:\nmain([1, 3, 2, 4])\nthen it should return the dictionary:\n{1: 3, 3: 2, 2: 4}\n\nWhich of the following programs work(s) according to the requirements?", + "options": { + "a": "def main(l1):\n result = {}\n index = 0\n while True:\n index = index + 1\n if index >= len(l1):\n break\n else:\n result[l1[index]] = l1[index + 1]\n return result", + "b": "def main(l1):\n result = {}\n for index, value in zip(l1[:-1], l1[1:]):\n result[index] = value\n return result", + "c": "Both programs work as required", + "d": "Neither of the two programs works as required" + }, + "correct": "b", + "explanation": "Option B correctly zips each element with the following element and builds the required dictionary. Option A starts at index 1 and eventually tries to access past the end of the list.", + "code_context": "main([1, 3, 2, 4])\n# should return {1: 3, 3: 2, 2: 4}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows the pattern of initializing an empty dictionary 'y = {}' and populating it with 'y[key] = value' during a loop, which is central to evaluating Option A and B." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Lists and Sets' piece clarifies dictionary equality, helping a student understand that the key-value pairs define the dictionary identity." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-5", + "rationale": "The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question.", + "critical_piece_ids": [ + "aiq-5" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "Shows the pattern of initializing an empty dictionary 'y = {}' and populating it with 'y[key] = value' during a loop, which is central to evaluating Option A and B.", + "critical_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Lists and Sets' piece clarifies dictionary equality, helping a student understand that the key-value pairs define the dictionary identity.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The question relies entirely on understanding list slicing (l1[:-1], l1[1:]) and the zip() function to evaluate Option B. None of the provided snippets explain these concepts. Furthermore, the logic error in Option A (indexing) requires knowledge of 0-based indexing and the behavior of len() in loops, which is not clearly illustrated.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Crucial sequence manipulation concepts (slicing and zipping) are missing.", + "missing_concepts": [ + "List slicing (l1[:-1], l1[1:])", + "The zip() function for pairing elements", + "Off-by-one errors in while-loops with index incrementing" + ], + "proposed_fix": "Add a snippet or piece explaining the 'sliding window' pattern using zip and slicing, and another demonstrating why starting an index at 1 and accessing index+1 leads to errors." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "aiq-5", + "proposal": "Update the 'Higher-Order Patterns' piece to include zip(): 'zip(l1, l2) creates pairs of elements from two sequences. zip(l[:-1], l[1:]) is a common pattern to pair each element with its successor.'", + "why_helpful": "Directly explains the core logic of the correct answer (Option B).", + "why_maybe_unnecessary": "While helpful, it might be better as a standalone 'Sequence Manipulation' snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:18:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q17", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q17", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-2", + "question": "What will be printed by the following program?", + "options": { + "a": "True", + "b": "False", + "c": "An error message", + "d": "None" + }, + "correct": "a", + "explanation": "Dictionary equality compares key-value contents rather than insertion order. Since both dictionaries contain the same pairs, the comparison prints True.", + "code_context": "d1 = {1: 5, 4: 6}\nd2 = {4: 6, 1: 5}\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are." + }, + { + "item_id": "aiq-1", + "rationale": "Contains a reference to a dictionary ('characters') and mentions checking if methods mutate lists in place, providing some context that dictionaries involve keys and values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the `{}` syntax for dictionaries." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are.", + "critical_piece_ids": [ + "exam-trial_midterm-10-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-1", + "rationale": "Contains a reference to a dictionary ('characters') and mentions checking if methods mutate lists in place, providing some context that dictionaries involve keys and values.", + "critical_piece_ids": [ + "aiq-1" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the `{}` syntax for dictionaries.", + "needed_piece_ids": [ + "exam-trial_midterm-10-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain that dictionary equality (`==`) in Python compares the content (key-value pairs) regardless of the order in which they were defined. A student with zero knowledge would likely guess based on the numbers being the same, but wouldn't know for certain if order matters in Python collections.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets identify dictionaries but fail to explain the 'unordered' nature of standard dictionary comparison.", + "missing_concepts": [ + "dictionary equality comparison", + "order-insensitivity of dictionary contents for ==" + ], + "proposed_fix": "Add a snippet or AI question that specifically addresses how Python compares dictionaries vs lists (where order does matter)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new AI piece: 'Dictionary Equality: Two dictionaries are considered equal (==) if they have the same key-value pairs, regardless of the order in which the pairs were added. Example: {1: 'a', 2: 'b'} == {2: 'b', 1: 'a'} is True.'", + "why_helpful": "It directly addresses the core logic of the exam question which tests content-based comparison vs order-based comparison.", + "why_maybe_unnecessary": "If the student assumes Python behaves 'intuitively' regarding sets of data, they might guess correctly, but it's a specific language rule.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:18:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-24-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-24-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA The code will result in an error.\nB True\nC None\nD False\nEnd of test Trial Midterm - Introduction to Pyth" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:aiq-1", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Condition flow and branch result\nExam • midterm_2024 • Q1\nConsider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • trial_midterm • Q2" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types.\nI is correct (e.g. a=1, b=2, both int). II is incorrect — if two objects have the same value " + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Operators and Truth", + "subtopic_title": "", + "search_text": "What is the result of (a//b)*b + a%b?\nArithmetic operators" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Mutable default argument\nCheck whether the method mutates the list in place and what the list looks like after each call.\nMutable default argument" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • trial_midterm • Q17\nA def square" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q18", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q18", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-3", + "question": "d1 = {1: 2, 2: 1}\n\nThe following code segments all print exactly the same output, except for one. Which one?", + "options": { + "a": "result = 1\nfor x in d1.values():\n result *= x\nprint(result)", + "b": "result = -1\nfor x in d1.keys():\n result += d1[x]\nprint(result)", + "c": "result = 4\nfor x in d1.items():\n result = result // x[1]\nprint(result)", + "d": "result = -4\nfor x in d1:\n result /= d1[x]\nprint(result)" + }, + "correct": "d", + "explanation": "A, B, and C all print 2. Option D uses true division starting from -4, so it prints -2.0 instead, making it the odd one out.", + "code_context": "d1 = {1: 2, 2: 1}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Provides a basic example of dictionary structure and calculation, though it lacks the specific methods (.values, .items) needed for this question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Provides a basic example of dictionary structure and calculation, though it lacks the specific methods (.values, .items) needed for this question.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The snippets do not define '.values()', '.keys()', or '.items()', nor do they explain that '.items()' yields tuples where indexing (x[1]) is required. Crucially, there is no explanation of the difference between true division (/) and floor division (//), which is the primary reason Option D is the odd one out (producing a float).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing definitions for dictionary iteration methods and the semantic difference between division operators.", + "missing_concepts": [ + "dict.values()", + "dict.keys()", + "dict.items()", + "Tuple indexing in loops (x[1])", + "True division (/) vs Floor division (//)" + ], + "proposed_fix": "Add a reference item covering dictionary iteration methods and a section on arithmetic operators highlighting float vs int outputs." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Dictionary Iteration & Division' that shows: 1) 'for x in d.values()' yields values. 2) 'for x in d.items()' yields (key, value) pairs, accessible via x[1]. 3) '/' always returns a float (e.g., 4 / 2 = 2.0) while '//' returns an integer (4 // 2 = 2).", + "why_helpful": "This allows a zero-knowledge student to map the code options to their results and identify why Option D (using /) produces a different type/value than the others.", + "why_maybe_unnecessary": "No reason to skip; this is a common 'trick' question type in the exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:19:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q19", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q19", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-1", + "question": "Suppose that you have a string called s1, which contains several letters. The letter \"x\" and the letter \"y\" occur exactly once in the string, and \"x\" always precedes \"y\".\n\nYou'd like to print out a string that looks just like s1, except that the letters \"x\" and \"y\" should be swapped.\n\nFor example, if:\ns1 = \"axbyc\"\nthen you'd like to print:\naybxc\n\nReminder: The replace string method has a third argument, which allows you to specify the maximum number of replacements you want to make, counting from left to right.", + "options": { + "a": "s1 = s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "b": "s1 = s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)", + "c": "s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "d": "s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)" + }, + "correct": "b", + "explanation": "Option B first changes the single y to x, then changes the first x from left to right back to y, which swaps the two letters. Options C and D do not assign the new string back to s1, and A changes the first replacement back incorrectly.", + "code_context": "s1 = \"axbyc\"\n# desired printed result: aybxc" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions return values (or None) and needs to be captured, which is helpful for understanding why Options C and D (which lack assignment) are incorrect." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-2", + "rationale": "This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic.", + "critical_piece_ids": [ + "aiq-2" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions return values (or None) and needs to be captured, which is helpful for understanding why Options C and D (which lack assignment) are incorrect.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain string immutability (the fact that .replace() returns a NEW string and does not modify the original). Without this knowledge, a student cannot distinguish between Options A/B and C/D. Additionally, there is no explanation of the left-to-right execution of chained .replace() calls, which is necessary to understand why B is correct and A is not.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The provided snippets focus on slicing, lists, and OOP, completely missing string method mechanics and the concept of immutability.", + "missing_concepts": [ + "String Immutability (methods return new strings; they don't mutate in place)", + "str.replace() behavior and argument order", + "Method Chaining execution order (left-to-right)" + ], + "proposed_fix": "Add a snippet specifically for 'String Immutability' and 'The .replace() method' showing that s.replace() requires s = s.replace() to save changes." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Immutability and .replace()\nContent:\nStrings are IMMUTABLE. Methods like .replace() do NOT change the original string; they return a NEW string.\nCorrect: s = s.replace('a', 'b')\nIncorrect: s.replace('a', 'b') (original 's' remains unchanged)\n\nChained methods: s.replace('x', 'y').replace('y', 'z')\nPython executes from left to right. The second .replace() sees the result of the first one.", + "why_helpful": "This directly addresses the two main pitfalls of the question: the need for reassignment (assignment back to s1) and the sequential logic of swapping characters.", + "why_maybe_unnecessary": "The question contains a 'Reminder' about the 3rd argument, but it does not remind the student about immutability or execution order.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:19:44Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "Slicing negative step\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.\nSlicing negative step" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q20", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q20", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-2", + "question": "Take a look at the following function definition.\n\nWhat will be returned by the following function call:\nglue(a='e', b='d')", + "options": { + "a": "ab", + "b": "cd", + "c": "ba", + "d": "dc" + }, + "correct": "c", + "explanation": "The function iterates over the keyword names in insertion order (`a`, then `b`) and prepends each key to the current result. Starting from the empty string, that produces `a`, then `ba`.", + "code_context": "def glue(**kwargs):\n result = ''\n for el in kwargs.keys():\n result = el + result\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Demonstrates the syntax for iterating over keys in a dictionary-like structure (for key in x), which is essential for tracing the 'for el in kwargs.keys()' loop." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents.", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "Demonstrates the syntax for iterating over keys in a dictionary-like structure (for key in x), which is essential for tracing the 'for el in kwargs.keys()' loop.", + "critical_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain that **kwargs handles multiple keyword arguments and show how loops iterate over keys. However, they do not explicitly state that the 'keys' in **kwargs are the argument names (the strings 'a' and 'b') or that Python preserves the insertion order of these arguments, which is critical to deciding between 'ab' and 'ba'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is no explicit explanation that **kwargs keys map to the argument names and follow the order of the function call.", + "missing_concepts": [ + "**kwargs dictionary mapping (parameter names as keys)", + "Keyword argument insertion order preservation", + "Behavior of .keys() on a **kwargs object" + ], + "proposed_fix": "Add a snippet clarifying that **kwargs collects parameters into a dictionary where the names (the left side of the '=') are keys, and that they are processed in the order they appear in the call." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Concept: Keyword Arguments (**kwargs). In a function definition like def f(**kwargs), 'kwargs' is a dictionary. If you call f(x=1, y=2), the keys are the strings 'x' and 'y', and the values are 1 and 2. Python remembers the order: 'x' comes before 'y' in loops.", + "why_helpful": "This directly bridges the gap between the function call and the loop behavior in the question.", + "why_maybe_unnecessary": "A student might guess that 'a' and 'b' are the keys, but knowing they are strings and follow order is specific technical knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:20:19Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q21", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q21", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-3", + "question": "Take a look at the following function definition.\n\nWhat will be printed to the screen by the following code?\nprint(tester())", + "options": { + "a": "1", + "b": "-1", + "c": "0", + "d": "None" + }, + "correct": "a", + "explanation": "The default argument is `0`, which satisfies the non-negative condition, so the function returns `1` and `print` outputs `1`.", + "code_context": "def tester(i1 = 0):\n if i1 >= 0:\n return 1\n\n if i1 < 0:\n return -1" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly shows a function definition with multiple default arguments (num2=10, num3=20) and demonstrates how the function behaves when some arguments are omitted in the call, which is the core concept needed to solve the tester() question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly shows a function definition with multiple default arguments (num2=10, num3=20) and demonstrates how the function behaves when some arguments are omitted in the call, which is the core concept needed to solve the tester() question." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains that print() is a built-in function that outputs its argument to the screen, helping the student understand the final step of the code execution." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Reinforces the concept of default arguments by stating 'y defaults to 11' in its explanation of a function call." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly shows a function definition with multiple default arguments (num2=10, num3=20) and demonstrates how the function behaves when some arguments are omitted in the call, which is the core concept needed to solve the tester() question.", + "critical_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Explains that print() is a built-in function that outputs its argument to the screen, helping the student understand the final step of the code execution.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "Reinforces the concept of default arguments by stating 'y defaults to 11' in its explanation of a function call.", + "critical_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets effectively explain the two potential hurdles: how default arguments work when a function is called without them, and what the print function does with the return value.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover default arguments and the print function well. There is no explicit breakdown of comparison operators like '>=' but they are intuitive enough for a general student.", + "missing_concepts": [ + "explicit explanation of comparison operators (>=, <)" + ], + "proposed_fix": "Add a small knowledge snippet defining common comparison operators (>, <, >=, <=, ==, !=)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A lecture-style snippet explaining default parameter values: 'When you define a function like def f(x=0), if you call f() without any arguments, Python automatically sets x to 0.'", + "why_helpful": "This would be the most direct 'rule' for a student to apply to this specific question.", + "why_maybe_unnecessary": "Existing exam snippets show this behavior through examples, which might be sufficient for pattern recognition.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:20:41Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
    • A function is a grouping of code that can perform a certain task and can be re-used \n
    • Print is a built-in function, tha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q22", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q22", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "List lambda 2", + "question": "Assume that you have a variable called x, which contains a list of integers.\n\nWhich of the following code segments will create another list that has every element of x multiplied by 2?\n\nFor example, if\nx = [1, 2, 3, 4, 5]\nthen which of the following code segments will result in the list:\n[2, 4, 6, 8, 10]", + "options": { + "a": "list(map(lambda i : i * 2, x))", + "b": "[(lambda i : i * 2)(item) for item in x]", + "c": "y = lambda i : i * 2\n[y(i) for i in x]", + "d": "All three code segments would work as intended" + }, + "correct": "d", + "explanation": "Each option constructs the doubled list correctly: `map` with a lambda, an immediately called lambda inside a list comprehension, and a named lambda used inside a list comprehension all apply `i * 2` to every element of `x`.", + "code_context": "x = [1, 2, 3, 4, 5]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a)." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates the 'list()' constructor being used to wrap an iterable, which helps explain the structure of the code in option (a)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a).", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates the 'list()' constructor being used to wrap an iterable, which helps explain the structure of the code in option (a).", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The candidate snippets completely lack an explanation of 'lambda' (anonymous functions) and 'list comprehensions', which are the two most critical concepts required to evaluate the code segments in this question.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete absence of documentation for functional programming primitives (lambda, map) and Pythonic iteration (list comprehensions) in the provided candidates.", + "missing_concepts": [ + "lambda syntax (lambda arguments : expression)", + "built-in Python map() function", + "list comprehension syntax [expr for item in iterable]", + "immediately called lambda expressions" + ], + "proposed_fix": "Add a 'Functional Programming and Comprehensions' snippet that covers lambda definitions, the built-in map() function, and the transformation pattern in list comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Anonymous Functions (Lambda) and Iteration Tools' explaining: 1. Lambda syntax. 2. How the built-in map() function applies a function to a list. 3. Basic list comprehension syntax for transforming data.", + "why_helpful": "This question tests if the student recognizes that a lambda can be passed to map, called immediately inside a comprehension, or assigned to a variable and then called. None of these behaviors are covered by existing snippets.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:21:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q23", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q23", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "List logic 2", + "question": "Which of the following programs creates a new list y, in which the elements are those elements of list x that are equal to their indices?\nYou can assume x consists of unique integers.\n\nFor example, if:\nx = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\nthen the program should create a new list y such that:\ny = [0, 3, 6, 7, 8, 10]", + "options": { + "a": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(i)", + "b": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(j)", + "c": "y = [i for i in x if i == x.index(i)]", + "d": "All three programs would work as intended" + }, + "correct": "d", + "explanation": "In A and B, whenever `i == j`, appending either `i` or `j` gives the same value because the index equals the element. In C, `x.index(i)` returns the position of `i`, so the comprehension keeps exactly the elements equal to their indices. Therefore all three programs work.", + "code_context": "x = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\n# target result:\ny = [0, 3, 6, 7, 8, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Although it uses Pandas, it discusses using a 'boolean mask on the index' to select specific elements, which introduces the student to the concept of index-based selection logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes a transformation where elements are compared to a 'mean of the elements', reinforcing the pattern of evaluating list/series values against a common property." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Although it uses Pandas, it discusses using a 'boolean mask on the index' to select specific elements, which introduces the student to the concept of index-based selection logic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes a transformation where elements are compared to a 'mean of the elements', reinforcing the pattern of evaluating list/series values against a common property.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the provided snippets explain 'enumerate()', list comprehensions for filtering, or the 'list.index()' method. Without knowing how 'enumerate' unpacks into an index and a value, a student with zero prior knowledge cannot distinguish between options A, B, and C.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a total lack of foundational list manipulation and iteration utilities in the candidate pool.", + "missing_concepts": [ + "enumerate() usage for index/value pairs", + "List comprehension syntax for filtering", + "list.index(item) method behavior" + ], + "proposed_fix": "Create a new snippet specifically covering 'List Iteration and Filtering' that demonstrates enumerate and basic comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: List Filtering and Indexing. Content: 1. `enumerate(x)` allows you to loop through a list and get both the position (index) and the item: `for i, item in enumerate(x):`. 2. List comprehensions filter data: `[item for item in x if condition]`. 3. `x.index(val)` finds where `val` first appears in list `x`.", + "why_helpful": "This directly maps to all three logical implementations (A, B, and C) shown in the question, enabling the student to see why they are equivalent.", + "why_maybe_unnecessary": "It is a basic concept, but crucial for 'List Logic' questions which are frequent in the syllabus.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:21:39Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q24", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q24", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "List loop 2", + "question": "Assume that you have a list called x, which is a list of multiple sub-lists containing integers.\n\nWhich of the following programs will create a new list y that is equal to the sub-list of x whose sum of elements is the highest?\n\nYou can assume that the sum of elements in each sub-list is a different number, so that there is only one that is the highest.\n\nFor example, if:\nx = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\nthen y should be:\ny = [8, 20, 300]", + "options": { + "a": "y = max(x)", + "b": "z = []\nfor i in x:\n z.append(sum(i))\ny = x[z.index(max(z))]", + "c": "x.sort()\ny = x[-1]", + "d": "y = [i for i in x if sum(i) == max(x)]" + }, + "correct": "b", + "explanation": "Option B computes the sum of each sub-list, finds the position of the largest sum, and then returns the corresponding original sub-list. The other options compare lists lexicographically or compare a numeric sum against `max(x)`, which is a list.", + "code_context": "x = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\n# target result:\ny = [8, 20, 300]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items." + }, + { + "item_id": "aiq-2", + "rationale": "Includes examples of list methods like .append(), which is used in the correct answer's loop to build the helper list." + }, + { + "item_id": "aiq-4", + "rationale": "Provides a hint about list properties and equality (e.g., [1,2]==[2,1] is False), though it lacks specific lexicographical comparison details." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "aiq-2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "Includes examples of list methods like .append(), which is used in the correct answer's loop to build the helper list.", + "critical_piece_ids": [ + "aiq-2" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Provides a hint about list properties and equality (e.g., [1,2]==[2,1] is False), though it lacks specific lexicographical comparison details.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets fail to define the 'sum()' function, the 'max()' function, and the 'list.index()' method, all of which are essential to understanding the correct option (B). Furthermore, there is no explanation of lexicographical comparison, which is necessary to understand why 'max(x)' in options A and D compares the first elements of the sub-lists rather than their sums.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The student lacks definitions for the core built-in functions (sum, max) and list methods (index) used in the logic, as well as the concept of list-of-lists comparison behavior.", + "missing_concepts": [ + "sum() function on lists", + "max() function on lists of integers", + "list.index() method", + "Lexicographical comparison of lists (how max() works on a list of lists)" + ], + "proposed_fix": "Add a snippet explicitly covering 'Aggregations and Search' that defines sum(), max(), and .index(), and another piece clarifying that max([[100], [200, 1]]) compares the first elements (100 vs 200) rather than the total count or sum." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: List Aggregations. Content: Explain sum(mylist) returns the total of elements; max(mylist) returns the largest element; mylist.index(x) returns the position of x. Add a warning that max() on a list of lists compares them element-by-element (e.g., [2, 1] > [1, 100]).", + "why_helpful": "This directly enables the student to parse the logic in Option B and realize why Option A is incorrect.", + "why_maybe_unnecessary": "If the student already understands these standard Python functions from basic lecture notes, but the goal is zero prior knowledge support.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:22:05Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q01", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q01", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_2", + "question": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\n- If they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\n- If they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?", + "options": { + "a": "if destination in europe:\n print('No passport needed. Bring your ID card.')\nelse:\n print('Please bring your passport.')", + "b": "if destination in europe:\n return 'No passport needed. Bring your ID card.'\nelif destination not in europe:\n return 'Please bring your passport.'", + "c": "for country in europe:\n if destination = country:\n print('No passport needed. Bring your ID card.')\n else:\n print('Please bring your passport.')", + "d": "for country in europe:\n if destination != country:\n return 'Please bring your passport.'\n else:\n return 'No passport needed. Bring your ID card.'" + }, + "correct": "a", + "explanation": "Option A directly checks whether destination is in the list of European countries and prints the correct message in each case. The other options either use the wrong control flow or invalid syntax.", + "code_context": "europe = [...]\ndestination = ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows a list-based scenario where the goal is to print formatted strings, reinforcing the use of print() over return." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "This piece contains the exact text and logic of the current question, providing the answer directly." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows a list-based scenario where the goal is to print formatted strings, reinforcing the use of print() over return.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the identical past exam piece, there is no snippet provided that explains the 'in' operator for membership testing or the basic 'if-else' control flow syntax. While 'aiq-4' helps eliminate 'return' options, the student cannot distinguish between the correct 'in' check and the logically flawed 'for' loop in option (c).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to explain membership operators and basic conditional logic outside of a function context.", + "missing_concepts": [ + "Membership operators (in, not in)", + "Basic if-else syntax", + "Comparison (==) vs Assignment (=)" + ], + "proposed_fix": "Add a foundational snippet covering membership testing in lists/strings and basic if-else blocks that use print statements." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Membership and Logic' explaining: 1. Using 'in' to check if a value exists in a list. 2. The difference between 'if-else' (two branches) and 'for' loops (iterating over every item). 3. Printing versus returning in global script scope.", + "why_helpful": "It would directly address the 'in' operator used in the correct answer and help students avoid the 'for loop' trap in Option C.", + "why_maybe_unnecessary": "Basic logic is often considered prerequisite, but for 'zero knowledge' goals, it is essential.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:22:32Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q02", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q02", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_3", + "question": "Calling the function func_10 will produce an error. Which line of the following code segment produces the error?", + "options": { + "a": "'var_2 = var_1 * var'\nThis line produces the error because func_2() was not called and assigning the value to var_1, thus var_1 was referenced before being defined.", + "b": "'var_1 = var * 2'\nThis line produces the error because Python is confused about which value var should have.", + "c": "'def func_2(var):'\nThis line produces the error because the name var is already used for the argument of func_1() and cannot be used again as the name of the argument for func_2().", + "d": "'return var_2'\nThis line produces the error because one function cannot return two outputs." + }, + "correct": "a", + "explanation": "The inner function func_2 is defined but never called, so var_1 is never assigned before the line var_2 = var_1 * var tries to use it.", + "code_context": "def func_1(var):\n def func_2(var):\n var_1 = var * 2\n return var_1\n var_2 = var_1 * var\n return var_2" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Directly explains the core concept of local scope: names defined inside a function are local and only known within that function. This allows a student to conclude that var_1, defined inside func_2, cannot be accessed by func_1." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Directly explains the core concept of local scope: names defined inside a function are local and only known within that function. This allows a student to conclude that var_1, defined inside func_2, cannot be accessed by func_1." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Defines what a function is (a grouping of code), which helps a student with zero prior knowledge understand the structure of the nested 'def' blocks in the code segment." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "This piece describes an almost identical scenario with the same logic: an inner function (func_2) is defined but never called, making its local variables (var_1) inaccessible to the outer function (func_1)." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "Directly explains the core concept of local scope: names defined inside a function are local and only known within that function. This allows a student to conclude that var_1, defined inside func_2, cannot be accessed by func_1.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Defines what a function is (a grouping of code), which helps a student with zero prior knowledge understand the structure of the nested 'def' blocks in the code segment.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of defining what a function is and explaining that local variables are only known inside their function provides all the logical components needed to identify the scope error described in the correct option.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are sufficient for the intended logic. There is a minor typo in the question text (func_10 vs func_1), but the options and code context make the intended question clear.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:23:06Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
      • A function is a grouping of code that can perform a certain task and can be re-used \n
      • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q03", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q03", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[str, int, NoneType, bool, float, str, dict]", + "b": "[str, int, NoneType, bool, float, bool, dict]", + "c": "[str, int, NoneType, bool, float, str, list]", + "d": "[str, float, NoneType, bool, int, str, dict]" + }, + "correct": "a", + "explanation": "The function appends the type of each element in the input list in order: string, integer, NoneType, boolean, float, string, and dictionary.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n list_2.append(type(item))\n return list_2\n\nmain(['abc', 0, None, True, 123.456, 'False', {}])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-cb3a9e3fd2", + "rationale": "Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner." + }, + "top_three_snippets": [ + { + "item_id": "ks-cb3a9e3fd2", + "rationale": "Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner." + }, + { + "item_id": "ks-eae9bf47dd", + "rationale": "Confirms that 'dict' is one of the standard Python types, which is necessary to identify the {} element." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-cb3a9e3fd2", + "rationale": "" + }, + { + "item_id": "ks-eae9bf47dd", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This piece contains the exact same code elements ('abc', 0, None, True, 123.456, 'False', {}) and explicitly maps them to their types, including the 'None' to 'NoneType' mapping and the 'False' in quotes as 'str' distinction." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-cb3a9e3fd2", + "rationale": "Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner.", + "critical_piece_ids": [ + "ks-cb3a9e3fd2" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-eae9bf47dd", + "rationale": "Confirms that 'dict' is one of the standard Python types, which is necessary to identify the {} element.", + "critical_piece_ids": [ + "ks-eae9bf47dd" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-cb3a9e3fd2", + "rationale": "", + "needed_piece_ids": [ + "ks-cb3a9e3fd2" + ] + }, + { + "snippet_id": "item:ks-eae9bf47dd", + "rationale": "", + "needed_piece_ids": [ + "ks-eae9bf47dd" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "high", + "rationale": "The general snippets cover str, int, bool, float, and dict. However, 'NoneType' is missing from all lecture snippets, and the 'type()' function is not explicitly defined outside of exam context explanations. The 'False' string vs. boolean distinction is also only explicitly clarified in the near-identical exam piece.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Lecture snippets define the names of types but lack examples for 'None/NoneType' and do not explicitly define the 'type()' function.", + "missing_concepts": [ + "NoneType", + "type() function behavior" + ], + "proposed_fix": "Add 'None' to the '8 types to know' lecture snippet and include a small section explaining that 'type(x)' returns the type name of object x." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-cb3a9e3fd2", + "proposal": "Add 'var_9 = None # NoneType' to the example list and include a note: 'type() returns these type names (e.g., type(123) is int)'.", + "why_helpful": "Allows students to answer questions involving None and type() without relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:23:32Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:ks-d9760d8cd8", + "snippet_label": "Conversion and Truthiness", + "week": 2, + "topic": "Conversion and Truthiness", + "pieces": [ + { + "item_id": "ks-d9760d8cd8", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Conversion and Truthiness", + "subtopic_title": "", + "search_text": "Type conversion (explicit)\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().\nExplicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\n" + } + ] + }, + { + "snippet_id": "item:ks-eae9bf47dd", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "ks-eae9bf47dd", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Mutable vs immutable types\nImmutable: int, float, str, bool, tuple. Mutable: list, dict, set. The value of a mutable object CAN be changed in-place. The value of an immutable object CANNOT be changed — a new object must be created.\nList is mutable — can change element in place\nl1" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:ks-cb3a9e3fd2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "ks-cb3a9e3fd2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Object types — the 8 types to know\nint, float, str, bool, tuple, list, dict, set\nAll 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q04", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q04", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 1", + "question": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\n\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97", + "options": { + "a": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou'}", + "b": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou' if vowel in 'aeiou'}", + "c": "Both of the code segments work correctly.", + "d": "Neither of the code segments work correctly." + }, + "correct": "c", + "explanation": "Both comprehensions produce the same dictionary because the extra condition in option B is always true for characters drawn from 'aeiou'.", + "code_context": "print(vowels_ASCII)\n# expected: {'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates dictionary creation with an 'if' filtering clause, which is relevant to evaluating Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "This piece contains the exact same question prompt about creating the 'vowels_ASCII' dictionary." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates dictionary creation with an 'if' filtering clause, which is relevant to evaluating Option B.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the identical question prompt is found, the snippets themselves are truncated and do not show the full code solutions or explanations for the 'ord()' function and dictionary comprehension syntax. A student with zero knowledge would see the pattern but lack the specific function definitions.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide examples of the desired output and similar problems, but lack the foundational syntax for dictionary comprehensions and the definition of the 'ord()' function.", + "missing_concepts": [ + "Dictionary comprehension syntax {k: v for x in iterable}", + "ord() function purpose and usage", + "Effect of redundant 'if' conditions in comprehensions" + ], + "proposed_fix": "Add a conceptual snippet from Week 2 lecture materials that explains dictionary comprehensions and common built-in functions like ord()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Dictionary Comprehensions' snippet from Week 2 materials showing the syntax: `{key_expr: value_expr for item in iterable if condition}`.", + "why_helpful": "It would allow the student to understand how Option A and Option B are constructed and why the redundant 'if' in B doesn't invalidate the result.", + "why_maybe_unnecessary": "The 'hint' in the question itself explains ord(), so a separate snippet for that might be overkill if the syntax is understood.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:23:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q05", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q05", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 1", + "question": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = (goals1, goals2, goals3)", + "b": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = [goals1 + goals2 + goals3]", + "c": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = [goals1, goals2, goals3]", + "d": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = (goals1, goals2, goals3)" + }, + "correct": "a", + "explanation": "Option A uses enumerate with start=1 to create the correct match-number keys and stores each triple of goal counts as a tuple. The other options either use the wrong value shape or start indexing from 0.", + "code_context": "player1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\nprint(match_goals)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a conceptual parallel for creating a dictionary from two separate lists (names and ages), which helps a student understand the 'key: value' mapping logic required here." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a conceptual parallel for creating a dictionary from two separate lists (names and ages), which helps a student understand the 'key: value' mapping logic required here." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary ('roman_nums') where keys are integers 1 to 5, which helps validate that the match numbers in the question should be the keys, not the values." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the task of creating a dictionary from a list of items, reinforcing the pattern of iterating to populate a new dictionary." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "This is the exact same question, including the specific player names, goal lists, and desired dictionary output." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a conceptual parallel for creating a dictionary from two separate lists (names and ages), which helps a student understand the 'key: value' mapping logic required here.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary ('roman_nums') where keys are integers 1 to 5, which helps validate that the match numbers in the question should be the keys, not the values.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the task of creating a dictionary from a list of items, reinforcing the pattern of iterating to populate a new dictionary.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam question is present in the database, making the answer directly findable. However, without the identical piece, the other snippets only describe problems and do not provide the specific syntax for 'enumerate(start=1)' or 'zip'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While there are many 'create a dictionary' exam prompts, none of the general snippets (excluding the identical one) explicitly show the syntax for 'zip()' or 'enumerate(..., start=1)'.", + "missing_concepts": [ + "syntax for enumerate(iterable, start=1)", + "syntax for zip(list1, list2, list3)", + "distinction between tuple assignment (a, b) and list assignment [a, b] in dictionaries" + ], + "proposed_fix": "Add a reference snippet showing common 'Dictionary Construction Patterns' that explicitly includes examples of zip and enumerate." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet titled 'Dictionary Population from Lists' demonstrating: 1. zip() to combine lists into values. 2. enumerate(..., start=1) to create sequential keys.", + "why_helpful": "It teaches the underlying mechanics so a student can solve variations of this problem (e.g., if match numbers started at 0 or if the lists were nested).", + "why_maybe_unnecessary": "The current question bank already contains the exact problem, which acts as its own reference.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:24:25Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q06", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q06", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 1", + "question": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?", + "options": { + "a": "sales_subset = [monthly_sales[key] for key in list(monthly_sales.keys())[:3]]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "b": "sales_subset = monthly_sales[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "c": "sales_subset = list(monthly_sales.items())[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "d": "sales_subset = monthly_sales['January':'March']\naverage_sales = sum(sales_subset.values()) / len(sales_subset)\nprint(average_sales)" + }, + "correct": "a", + "explanation": "Option A first collects the values for the first three keys into a list and then computes the average correctly. The other options attempt unsupported dictionary slicing or try to sum tuples instead of numeric values.", + "code_context": "monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question." + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Shows the concept of summing values from a set of keyword arguments (which act like a dictionary)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "This is the exact same question as the one being evaluated, providing the correct answer directly." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Shows the concept of summing values from a set of keyword arguments (which act like a dictionary).", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the identical past exam piece, none of the snippets explain that dictionaries are unsliceable or how to correctly use list(d.keys())[:3] to get a subset of values. A student wouldn't know why options B, C, or D fail.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to address the core concept of the question: dictionary slicing limitations and the workaround using list conversion of keys.", + "missing_concepts": [ + "dictionaries do not support slicing (dict[:n])", + "slicing list(dict.keys()) to extract specific entries", + "dictionary .items() returns tuples, which cannot be summed directly" + ], + "proposed_fix": "Add a summary snippet or lecture piece explicitly stating that dictionaries cannot be sliced like lists and demonstrating the list(d.keys())[:n] pattern." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Dictionary Slicing and Subsets. Content: Dictionaries are unordered and do not support slicing (e.g., d[:3] or d['a':'c'] will raise an error). To get the first N items, convert keys to a list: `keys = list(my_dict.keys())[:3]`. Then use a list comprehension: `subset = [my_dict[k] for k in keys]`.", + "why_helpful": "It directly addresses the specific technical trap in the question and explains the correct alternative shown in Option A.", + "why_maybe_unnecessary": "The student might find the answer if they simply memorize the past exam question, but they won't understand the underlying 'why'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:24:51Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q07", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q07", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "[1, 4, 3, 8, 5]", + "b": "[2, 4, 6, 8, 10]", + "c": "[1, 2, 3, 4, 5]", + "d": "[2, 2, 6, 4, 10]" + }, + "correct": "a", + "explanation": "The list comprehension doubles only the even numbers and leaves the odd numbers unchanged, so the result is [1, 4, 3, 8, 5].", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x * 2 if x % 2 == 0 else x for x in numbers]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question." + }, + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "Reinforces the logic of the modulo operator (i % 2 == 0) in a different context (while loops), helping a student confirm that this expression identifies even numbers." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "Reinforces the logic of the modulo operator (i % 2 == 0) in a different context (while loops), helping a student confirm that this expression identifies even numbers.", + "critical_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain 'list comprehension' and the even-number check (% 2 == 0). However, they do not explain the ternary 'if-else' syntax within a comprehension (val if cond else other), which is the specific mapping logic used here. A student would have to infer that 'if' applies to the preceding expression.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate snippets cover list comprehensions with filters ([x for x in list if cond]) but lack examples of conditional mapping ([val_if if cond else val_else for x in list]).", + "missing_concepts": [ + "ternary operator / conditional expression syntax", + "conditional mapping in list comprehensions" + ], + "proposed_fix": "Add a snippet or piece that explains the 'value if condition else other_value' syntax, specifically within a list comprehension context." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet explaining 'Conditional Expressions in List Comprehensions'. Example: '[x * 2 if x > 2 else x for x in list] - This doubles items greater than 2 and keeps others the same.'", + "why_helpful": "This bridges the gap between simple filtering (which is in the current snippets) and the conditional mapping required by this specific question.", + "why_maybe_unnecessary": "A student might be able to guess the logic if they are familiar with 'if/else' in English, but the Python syntax 'val if cond else other' is counter-intuitive for beginners.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:26:18Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-5-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 !" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q08", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q08", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "['10a', '30c']", + "b": "[10, 20, 30, 40]", + "c": "['a', 'b', 'c', 'd']", + "d": "['10a', '20b', '30c', '40d']" + }, + "correct": "a", + "explanation": "The loop keeps only even indices from enumerate(list1), so it uses indices 0 and 2 and appends the concatenated strings '10a' and '30c'.", + "code_context": "list1 = [10, 20, 30, 40]\nlist2 = ['a', 'b', 'c', 'd']\n\nresult = []\n\nfor index, value in enumerate(list1):\n if index % 2 == 0:\n result.append(str(value) + list2[index])\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Provides an example of the .append() method, which is used to build the result list in the code segment." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "While focused on DataFrames, the rationale explains the concept of using a 'boolean mask on the index to find even numbers', reinforcing the parity selection logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "Necessary for understanding the % parity operator." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Necessary for understanding how append adds items to a list." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question.", + "critical_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Provides an example of the .append() method, which is used to build the result list in the code segment.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "While focused on DataFrames, the rationale explains the concept of using a 'boolean mask on the index to find even numbers', reinforcing the parity selection logic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "Necessary for understanding the % parity operator.", + "needed_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Necessary for understanding how append adds items to a list.", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover the modulo operator and list appending, but there is no explanation of the enumerate() function, which is critical for knowing that the loop variable 'index' refers to the position and 'value' refers to the content.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The primary gap is the lack of information regarding the enumerate() function and the behavior of string concatenation with converted integers.", + "missing_concepts": [ + "enumerate() function behavior", + "string concatenation (str(value) + list2[index])" + ], + "proposed_fix": "Add a snippet or AI question entry explaining that enumerate(list) provides pairs of (index, value) during iteration." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add an AI common question for 'enumerate() function': 'What does enumerate(mylist) do in a for loop?' Explanation: It returns both the index (position) and the value of each item in the list. Example: for i, v in enumerate(['a', 'b']): i is 0,1 and v is 'a','b'.", + "why_helpful": "The question relies entirely on knowing that 'index' is the numerical position provided by enumerate.", + "why_maybe_unnecessary": "Some students might guess 'index' means position from the variable name, but it is not guaranteed.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:27:08Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q09", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q09", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 2", + "question": "Suppose you have a list called mylist. You want to extract every third element starting from index 1 (inclusive) to the last index (inclusive) from that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\n\nthen executing the following command:\nprint(subset)\n\nshould return:\n[15, 30, 45]\n\nWhat should the blanks be filled with?", + "options": { + "a": "1:len(mylist):3", + "b": "0:len(mylist):3", + "c": "1:len(mylist)-1:3", + "d": "0:len(mylist)-1:3" + }, + "correct": "a", + "explanation": "Starting at index 1 and stepping by 3 gives positions 1, 4, and 7, which are 15, 30, and 45. Using len(mylist) as the stop value includes the last valid stepped element.", + "code_context": "subset = mylist[___:___:___]\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\nprint(subset)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-3", + "rationale": "This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded." + }, + "top_three_snippets": [ + { + "item_id": "aiq-3", + "rationale": "This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-3", + "rationale": "It is the only family in the candidate set that provides examples of list stepping and explains index-based exclusion logic." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-3", + "rationale": "This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded.", + "critical_piece_ids": [ + "aiq-3" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-3", + "rationale": "It is the only family in the candidate set that provides examples of list stepping and explains index-based exclusion logic.", + "needed_piece_ids": [ + "aiq-3" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The necessary concepts (start position, step size, and 'stop' exclusion) are all present in the aiq-3 family. However, a student must synthesize the 'stop is excluded' rule from the range() piece and apply it to the slicing examples, as there isn't a single piece that defines the full [start:stop:step] syntax in one rule.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets lack a direct definition of the three-part list slicing syntax [start:stop:step] in a unified rule.", + "missing_concepts": [ + "Explicit definition of the list[start:stop:step] syntax", + "Direct rule stating that for slicing, index 'stop' is excluded" + ], + "proposed_fix": "Add a foundational snippet explaining list[start:stop:step] where start is inclusive, stop is exclusive, and step is the increment." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new rule snippet: 'List Slicing (Start:Stop:Step)'. Rule: Use list[start:stop:step] to extract elements. 'start' is the first index included; 'stop' is the boundary (not included); 'step' is how many indices to jump. Example: mylist[1:8:3] starts at index 1 and takes every 3rd element until index 7.", + "why_helpful": "This provides the exact structural knowledge needed to fill in the blanks without having to infer it from separate examples.", + "why_maybe_unnecessary": "A clever student might eliminate options b and d (starting at 0) and then use the 'stop is excluded' hint from range() to choose 'len(mylist)' over 'len(mylist)-1'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:27:45Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Correct. c: [::-1] reverses to [10,9,8,7,6,5,4,3,2,1], then [::2] takes every 2nd: [10,8,6,4,2]. Correct. d: [::2] gives [1,3,5,7," + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q10", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q10", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_1", + "question": "Suppose you have the following function:\n\nWhat will be printed by the following line of code?\nprint(main())", + "options": { + "a": "True", + "b": "False", + "c": "0", + "d": "None" + }, + "correct": "d", + "explanation": "The default value of x is 0, so neither if-condition runs and the function reaches the end without returning anything, which prints None.", + "code_context": "def main(x = 0):\n if x > 0:\n return True\n\n if x < 0:\n return False\n\nprint(main())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "Directly explains that if a function's return statement is not reached, it returns 'None'. This is the core concept tested by the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "Directly explains that if a function's return statement is not reached, it returns 'None'. This is the core concept tested by the question." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Provides an example of default argument values (e.g., num2=10), which helps a student understand that 'x=0' in the definition means 'x' starts at 0 when the function is called without arguments." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "Covers the 'Implicit return None' behavior." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Covers default argument behavior." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "Directly explains that if a function's return statement is not reached, it returns 'None'. This is the core concept tested by the question.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "Provides an example of default argument values (e.g., num2=10), which helps a student understand that 'x=0' in the definition means 'x' starts at 0 when the function is called without arguments.", + "critical_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "Covers the 'Implicit return None' behavior.", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "Covers default argument behavior.", + "needed_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the default argument rule and the implicit return rule provides all necessary information to solve the question without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are sufficient. The AI-generated 'Implicit return None' note is particularly effective for this question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:28:07Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q11", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q11", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_3", + "question": "Suppose you have a variable called x which contains a list of integers as follows:\nx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nWhich of the following lines will produce an output that is different from the rest?", + "options": { + "a": "print(len(x))", + "b": "print(sorted(x, reverse=True)[0])", + "c": "print(x.index(9))", + "d": "print(sum(x[4:6]))" + }, + "correct": "a", + "explanation": "len(x) is 10, while sorted(x, reverse=True)[0] is 9, x.index(9) is 9, and sum(x[4:6]) is 4 + 5 = 9.", + "code_context": "x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Reinforces the explanation of reverse sorting and basic list operations." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of slicing syntax (`alphabet[1::2]`), which helps a student interpret the `x[4:6]` slice in option D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Reinforces the explanation of reverse sorting and basic list operations.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of slicing syntax (`alphabet[1::2]`), which helps a student interpret the `x[4:6]` slice in option D.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover the complex `sorted` logic and provide context for slicing, they do not define the basic built-in functions `len()` and `sum()`, nor the list method `.index()`. A student with zero Python knowledge would have to rely on the English meaning of these words to guess their function.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to define several fundamental built-in functions and list methods used in the question options.", + "missing_concepts": [ + "len() function", + "sum() function", + "list.index() method" + ], + "proposed_fix": "Add a summary piece covering 'Common List Built-ins and Methods' that defines len, sum, and index." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new item explaining basic list operations: len(list) returns the count of items; sum(list) returns the total of numerical items; list.index(x) returns the position of the first occurrence of x.", + "why_helpful": "This would make the question fully answerable by defining the operations in options A, C, and D.", + "why_maybe_unnecessary": "These functions are named intuitively, but for a strict zero-knowledge context, they require formal definitions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:28:50Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q12", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q12", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_1", + "question": "You want to write a function called main which accepts a flexible number of integers as arguments.\n\nThe function should return a dictionary with the following key-value pairs:\n- key 'sum' has a value which is the sum of all the integers passed as arguments\n- key 'pro' has a value which is the multiplicative product of all the integers passed as arguments\n- key 'pow' has a value which is a list of all the squares of the integers passed as arguments\n\nWhich of the following lines of code will complete the function to give what you need?", + "options": { + "a": "x['sum'] = sum(args)\nx['pro'] = 1\nx['pow'] = []\nfor i in args:\n x['pro'] *= i\n x['pow'].append(i**2)", + "b": "x['sum'] = sum(args)\nx['pro'] = i for i in args\nx['pow'] = [i**2 for i in args]", + "c": "for i in args:\n x['sum'] = sum(args)\n x['pro'] *= i\n x['pow'] = [i**2 for i in args]", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "Option A correctly stores the sum, initializes the product accumulator to 1 before multiplying through the arguments, and builds the list of squares for each integer.", + "code_context": "def main(*args):\n x = {}\n\n # missing lines\n # ...\n\n return x" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "Piece 2 (multiply function) is the most critical as it demonstrates exactly how to handle a flexible number of arguments (*args) and the accumulator pattern for multiplication (total = 1 followed by total *= num). This allows the student to identify why option 'a' correctly initializes 'pro' to 1." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "Piece 2 (multiply function) is the most critical as it demonstrates exactly how to handle a flexible number of arguments (*args) and the accumulator pattern for multiplication (total = 1 followed by total *= num). This allows the student to identify why option 'a' correctly initializes 'pro' to 1." + }, + { + "item_id": "aiq-5", + "rationale": "Piece 1 (summarize function) shows how to return a dictionary with calculated values (like sum(nums)) using specific keys, which directly helps with the 'sum' and overall dictionary structure requirement." + }, + { + "item_id": "aiq-2", + "rationale": "Piece 2 shows the .append() method, which is used in option 'a' to build the 'pow' list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "aiq-5", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "Piece 2 (multiply function) is the most critical as it demonstrates exactly how to handle a flexible number of arguments (*args) and the accumulator pattern for multiplication (total = 1 followed by total *= num). This allows the student to identify why option 'a' correctly initializes 'pro' to 1.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "rationale": "Piece 1 (summarize function) shows how to return a dictionary with calculated values (like sum(nums)) using specific keys, which directly helps with the 'sum' and overall dictionary structure requirement.", + "critical_piece_ids": [ + "aiq-5" + ] + }, + { + "snippet_id": "item:aiq-2", + "rationale": "Piece 2 shows the .append() method, which is used in option 'a' to build the 'pow' list.", + "critical_piece_ids": [ + "aiq-2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Between aiq-4 and aiq-5, the student has examples of flexible arguments, dictionary construction, sum() usage, and the multiplication accumulator pattern. Option 'a' is the only one that uses the correct initialization (x['pro'] = 1) shown in the snippets.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic for sum and product is well-covered, the exponent operator (**) and initializing a dictionary key to an empty list are not explicitly demonstrated in a single context.", + "missing_concepts": [ + "exponent operator (**)", + "initializing an empty list inside a dictionary key" + ], + "proposed_fix": "Add a snippet or piece that demonstrates list building within a loop for squares or powers." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet piece showing: `results['squares'] = []; for i in numbers: results['squares'].append(i**2)`.", + "why_helpful": "It would explicitly cover the 'pow' list generation logic (initialization + append + exponent).", + "why_maybe_unnecessary": "Students might infer the power operator or recognize option 'a' as the only one with correct product logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:29:12Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 29, + "candidate_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments." + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Mutable arguments\nMutating a passed list changes the caller's object; rebinding the parameter does not.\nMutable arguments" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q13", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q13", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 2", + "question": "You have the following objects loaded in Python:\nitem = \"laptop\"\nprice = 1299.99\n\nYou need to print the following sentence:\nThe laptop is priced at $1299.99.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(message)", + "b": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(mesage)", + "c": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)", + "d": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)" + }, + "correct": "a", + "explanation": "Option A correctly uses positional placeholders and prints the defined variable `message`. Option B appears to use a misspelled variable name in the print call, and C/D mix named placeholders with positional arguments.", + "code_context": "item = \"laptop\"\nprice = 1299.99" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Mentions a specific string format (for a URL), but relates to the data format rather than the Python .format() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a basic print statement; however, it provides no help with the actual core of the question (string formatting)." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Mentions a specific string format (for a URL), but relates to the data format rather than the Python .format() method.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a basic print statement; however, it provides no help with the actual core of the question (string formatting).", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets cover string formatting techniques such as f-strings or the .format() method. The question specifically tests positional placeholders ({0}, {1}) and argument mapping in .format(), as well as recognizing variable name typos. The provided snippets focus on dictionaries, lists, and function arguments (**kwargs), which are unrelated.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Complete absence of documentation regarding string formatting and interpolation.", + "missing_concepts": [ + "The .format() method syntax", + "Positional placeholders ({0}, {1}) in strings", + "Argument mapping order in .format()", + "Basic variable name matching and typo detection" + ], + "proposed_fix": "Add a foundational snippet (from Week 1 or 2) that explicitly demonstrates f-strings and the .format() method, including how indices map to arguments." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet family 'String Formatting' with a piece showing: 1. .format() usage: 'Hello {0}, you have {1} messages'.format(name, count). 2. f-string usage: f'Hello {name}'. 3. Explicitly state that {0} refers to the first argument and {1} to the second.", + "why_helpful": "This question is a direct test of the .format() syntax and index mapping. Without a snippet explaining this, a student with no prior knowledge cannot distinguish between the correct positional mapping and the incorrect named/mixed options.", + "why_maybe_unnecessary": "If the cheat sheet is intended only for advanced data structures, this might be considered too 'basic', but it is clearly necessary for this specific exam question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:29:40Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q14", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q14", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 1", + "question": "Suppose you have run the following block of code:\n\nimport pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)\n\nWhich of the following lines of code give(s) the following output?\n1 4\n2 5\n3 6\nName: B, dtype: int64", + "options": { + "a": "df.loc[:, 'B']", + "b": "df['B'].loc[:]", + "c": "df['B']", + "d": "All of the given lines." + }, + "correct": "d", + "explanation": "Each of A, B, and C selects the same Series containing column `B`, so the correct choice is that all listed lines produce the shown output.", + "code_context": "import pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This snippet involves creating columns based on existing ones, which likely demonstrates the df['col'] syntax used in option C." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Mentions keeping specific columns when creating a new DataFrame, reinforcing the concept of column selection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This snippet involves creating columns based on existing ones, which likely demonstrates the df['col'] syntax used in option C.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Mentions keeping specific columns when creating a new DataFrame, reinforcing the concept of column selection.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets show examples of column access (df['A']) and filtered access (df.loc[...]), they do not explicitly teach the equivalence of df['B'], df.loc[:, 'B'], and df['B'].loc[:]. A student without prior knowledge would likely recognize df['B'] but would not have enough information to confirm that the other two syntaxes produce the exact same result.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing a clear explanation of pandas indexing equivalence rules for Series selection.", + "missing_concepts": [ + "Equivalence of bracket notation (df['col']) and .loc for column selection (df.loc[:, 'col'])", + "Understanding that .loc[:] on a Series is a redundant/identity operation", + "Fundamental difference between selecting a Series (column) and a DataFrame (subset)" + ], + "proposed_fix": "Add a foundational Pandas snippet specifically illustrating 'Equivalent Selection Methods' for columns, showing that basic brackets, .loc with a colon, and chained identity slices all return the same Series." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet 'Pandas Indexing: Column Retrieval' that explicitly lists df['B'], df.loc[:, 'B'], and s.loc[:] as valid/equivalent ways to interact with column data.", + "why_helpful": "This covers the 'trick' nature of the question where multiple syntaxes lead to the same result.", + "why_maybe_unnecessary": "It's a very specific syntax rule, but crucial for answering 'all of the above' questions in Pandas.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:30:06Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "Which of the following code lines could NOT have created df2 from df1?\nA\nB\nC\nD\nA\nOption A would sort all 5 rows of df1 and keep columns A, C, D, resulting in a 5-row DataFrame. df2 only has 3 rows (indices 4, 3, 2)." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q15", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q15", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_1", + "question": "Which code segment gives the same output as the following?\n\ndate = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))\n\nYou may assume that datetime and timedelta classess are already imported from the datetime module.", + "options": { + "a": "print(datetime.strptime('22-05-2023', '%d.%m.%Y'))", + "b": "print('02-05-2023')", + "c": "print(datetime.strptime('05.22.2023', '%d-%m-%Y'))", + "d": "date = datetime.strptime('10/05/2023', '%d/%m/%Y')\nprint((date + timedelta(days=5)).strftime('%m-%d-%Y'))" + }, + "correct": "b", + "explanation": "The original code parses May 12, 2023 and subtracts 10 days, so the printed result is the string `02-05-2023`.", + "code_context": "date = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Provides the fundamental definition of the print function, which is necessary to understand that the code's purpose is to output a specific string to the screen." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Provides the fundamental definition of the print function, which is necessary to understand that the code's purpose is to output a specific string to the screen.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "A student with zero Python knowledge cannot determine the output without knowing what the format codes '%m', '%d', and '%Y' represent. Specifically, they cannot know if '05.12' is May 12 or December 5, nor can they know how timedelta(days=-10) behaves without explicit documentation of those parameters.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets mention the existence of the Datetime module but do not define the specific syntax for parsing/formatting dates or the available attributes for timedelta initialization.", + "missing_concepts": [ + "datetime.strptime and datetime.strftime format codes (%d, %m, %Y)", + "Initialization parameters for timedelta (e.g., days=X)" + ], + "proposed_fix": "Add a lecture-based or reference snippet that defines common strftime/strptime format codes and provides a basic example of date arithmetic using timedelta." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a reference item for the datetime module: 'strptime(string, format)' and 'strftime(format)' with a table: %d (Day 01-31), %m (Month 01-12), %Y (Year 2023). Also define timedelta(days=n) for adding/subtracting days.", + "why_helpful": "This provides the 'dictionary' needed to translate the code into human-readable logic (May 12 - 10 days = May 02).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:30:33Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
        • A function is a grouping of code that can perform a certain task and can be re-used \n
        • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q16", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q16", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Easy_3", + "question": "You have the following definition for a class called Shape:\n\nWhat would be the output if we execute the following commands?\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "options": { + "a": "True", + "b": "False", + "c": "An error", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "`Shape(5, 3).area` is `5 * 3 = 15`, and `Shape(1, 15).length` is `15`, so the comparison evaluates to `True`.", + "code_context": "class Shape:\n def __init__(self, height, length):\n self.height = height\n self.length = length\n self.area = self.height * self.length\n\nprint(Shape(5, 3).area == Shape(1, 15).length)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Demonstrates the evaluation of equality (==) and logic in print statements, confirming that the output of such comparisons in Python is a boolean (True/False)." + }, + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Shows the syntax for instantiating a class with multiple arguments (Flight(...)), which helps clarify the 'Shape(5, 3)' part of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "rationale": "Demonstrates the evaluation of equality (==) and logic in print statements, confirming that the output of such comparisons in Python is a boolean (True/False).", + "critical_piece_ids": [ + "exam-midterm_2024-2-w2-conditions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Shows the syntax for instantiating a class with multiple arguments (Flight(...)), which helps clarify the 'Shape(5, 3)' part of the question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-2-w2-conditions" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets explain class definition, initialization, and boolean output, they don't explicitly show the 'dot notation' (e.g., .area) being used directly on a newly created instance. A student must infer that Shape(5, 3).area refers to the attribute created inside __init__.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate snippets are mostly exam prompts rather than direct reference material. They provide enough clues for a logical student to infer the answer, but they lack a concise explanation of attribute access on instance objects.", + "missing_concepts": [ + "Accessing attributes via dot notation on temporary instances", + "Explicit explanation of 'self' inside calculations in __init__" + ], + "proposed_fix": "Add a foundational reference snippet that explains the lifecycle: Class Call -> __init__ execution -> Attribute storage -> Dot notation retrieval." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Reference: OOP Basics. Calling Shape(5, 3) executes the __init__ method where arguments are assigned to self.attributes (e.g., self.area = 5*3). You can immediately access these using dot notation: Shape(5, 3).area.", + "why_helpful": "It directly explains the composite expression in the print statement which is the primary hurdle for a novice.", + "why_maybe_unnecessary": "The Vehicle class prompt already mentions that attributes are initialized at the time of object construction, which is a strong hint.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:31:05Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q17", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q17", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "6-string - operations - 2", + "question": "Write a function called shuffle_sentence that takes a string as an argument and returns a new string where the words are shuffled randomly.\n\nFor example, if your function is called as:\nshuffle_sentence(\"Hello, how are you today?\")\nthen it could return a shuffled string like:\n'how today? you Hello, are'\n\nWhich of the following programs work(s) according to the requirements?\n\nHints:\nThe shuffle() function is a method from the random module. The shuffle() method takes a sequence, like a list, and reorganizes the order of the items. This method changes the original list; it does not return a new list.\nThe reversed() function computes the reverse of a given sequence object and returns it in the form of a list.", + "options": { + "a": "def shuffle_sentence(sentence):\n words = sentence.split()\n return ' '.join(reversed(words))", + "b": "import random\n\ndef shuffle_sentence(sentence):\n words = sentence.split()\n random.shuffle(words)\n return ' '.join(words)", + "c": "Both of the programs work.", + "d": "Neither of the programs work." + }, + "correct": "b", + "explanation": "Option B is the only one that actually shuffles the words randomly. Option A only reverses the word order, which does not satisfy the random-shuffle requirement.", + "code_context": "shuffle_sentence(\"Hello, how are you today?\")\n# could return: 'how today? you Hello, are'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it)." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it)." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions without an explicit return (or returning None) result in None, which helps clarify the hint that shuffle() does not return a new list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-2", + "rationale": "This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it).", + "critical_piece_ids": [ + "aiq-2" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions without an explicit return (or returning None) result in None, which helps clarify the hint that shuffle() does not return a new list.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets help explain 'in-place mutation' and 'None return values', which are the 'traps' of the question. However, they do not provide any information on string split() or join() methods, which are required to understand the code structure. The question's internal hints are actually more helpful for the shuffle() behavior than the snippets.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover the logic of mutation but miss the specific string-list conversion methods used in both options.", + "missing_concepts": [ + "str.split()", + "str.join(list)" + ], + "proposed_fix": "Add a snippet demonstrating how to convert a sentence into a list of words using split() and how to recombine them into a string using join()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: String Operations. Description: Use 'text.split()' to turn a string into a list of words. Use '\" \".join(words)' to combine a list of strings into one string separated by spaces.", + "why_helpful": "The question relies on understanding how words are converted to a list for shuffling and then back to a string for the return value.", + "why_maybe_unnecessary": "The student might guess the meaning of split and join from the context of the word 'shuffle_sentence', but it is a significant leap for someone with zero knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:31:28Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Mutable arguments\nMutating a passed list changes the caller's object; rebinding the parameter does not.\nMutable arguments" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Generators and Iterators", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q18", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q18", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "6-strings - find & replace - 1", + "question": "Consider the following line of code:\n\ntext = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\n\nYou want to create a new string called new_text where all occurances of \"oil\" are replaced by \"natural gas\".\n\nSo:\nprint(new_text)\nshould return:\n\"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "new_text = ' '.join([word if word != 'oil' else 'natural gas' for word in text.split()])", + "b": "new_text = text.replace(\"oil\", \"natural gas\")", + "c": "new_text = text.split()\nfor index, word in enumerate(new_text):\n if word == 'oil':\n new_text[index] = 'natural gas'\nnew_text = ' '.join(new_text)", + "d": "All of the given options works as intended." + }, + "correct": "d", + "explanation": "All three code fragments replace each occurrence of the standalone word `oil` with `natural gas`, so the correct answer is that all of them achieve the requested result.", + "code_context": "text = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\nprint(new_text)\n# should return:\n# \"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Involves string formatting and character separation, providing a basic context for string-based function arguments." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Involves checking string properties (anagrams), which relates to the conditional logic used in option 'a' and 'c' of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Involves string formatting and character separation, providing a basic context for string-based function arguments.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Involves checking string properties (anagrams), which relates to the conditional logic used in option 'a' and 'c' of the question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-4-w2-conditions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The candidate snippets focus on dictionaries, functions, and Pandas. There is zero mention of the .replace(), .split(), or .join() string methods, nor is there an explanation of list comprehensions or the enumerate() function, all of which are critical to evaluating the four options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The knowledge base is missing foundational string manipulation methods and advanced iteration patterns (list comprehensions).", + "missing_concepts": [ + "str.replace(old, new) method", + "str.split() method for breaking strings into words", + "' '.join(list) method for combining words", + "List comprehensions with if-else logic", + "enumerate() for tracking list indices during iteration" + ], + "proposed_fix": "Add a dedicated snippet family for 'String Methods' and another for 'Iterables and List Comprehensions' containing examples of find/replace patterns." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet for Week 1/4 'Common String Operations' that demonstrates .replace(), .split(), and .join() using a simple text example.", + "why_helpful": "The question directly tests the equivalence of using these three methods to achieve the same result.", + "why_maybe_unnecessary": "The topic might be covered in lecture slides, but it is currently absent from the selectable 'key point' snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:31:55Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q19", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q19", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - hard - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Select all rows where the age is greater than 30 and the gender is \"Male\".\n- Operation 2: Create a new column called Sex_abbr of which the values should be \"F\" if gender is \"Female\" and \"M\" if gender is \"Male\".\n- Operation 3: Calculate the average salary of all employees.\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df_operation1 = df[(df['Age'] > 30) & (df['Gender'] == 'Male')]\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "b": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "c": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = df['Gender'].map(lambda x: 'M' if x == 'Male' else 'F')\ndf_operation3 = df['Salary'].sum()/len(df)", + "d": "df_operation1 = df[df['Age'] > 30 & df['Gender'] == 'Male']\ndf['Sex_abbr'].map(lambda x: 'M' if x == 'Male' else 'F' for x in df['Gender'])\ndf_operation3 = df['Salary'].sum()/len(df)" + }, + "correct": "a", + "explanation": "Option A correctly filters rows with both conditions using boolean masking, builds the abbreviation column from the Gender column, and computes the average salary with mean().", + "code_context": "Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions 'boolean mask', providing a conceptual link to row selection (Operation 1), though it lacks the specific syntax for multiple conditions." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions calculating the 'mean' of a pandas Series, which is the direct requirement for Operation 3." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions 'boolean mask', providing a conceptual link to row selection (Operation 1), though it lacks the specific syntax for multiple conditions.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions calculating the 'mean' of a pandas Series, which is the direct requirement for Operation 3.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets provide the high-level concepts (column creation, boolean masks, mean) but fail to show the specific syntax required for 'hard' pandas operations: 1) The use of bitwise '&' with mandatory parentheses for multiple filter conditions, and 2) The syntax for list comprehensions or lambda mapping used to derive new column values. A zero-knowledge student could guess based on keywords but wouldn't know why option 'a' is syntactically superior to 'd' (operator precedence) or 'b/c' (accessor syntax).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Critical syntax for multi-condition filtering and conditional column creation is missing.", + "missing_concepts": [ + "Pandas multi-condition boolean masking (using '&' and '|' with required parentheses)", + "Derived column creation using list comprehensions with if/else (ternary) logic", + "Correct accessor syntax for .loc vs standard brackets []" + ], + "proposed_fix": "Add a new snippet covering complex pandas selections and transformations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet 'Pandas Advanced Selection and Derived Columns' containing: 1. df[(df['A'] > x) & (df['B'] == y)] (emphasize parentheses), 2. df['new'] = ['val1' if x == 'y' else 'val2' for x in df['old']], 3. df['col'].mean().", + "why_helpful": "Directly addresses the syntax patterns used in this 'hard' level question, particularly the tricky operator precedence in filtering and the list comprehension pattern.", + "why_maybe_unnecessary": "If the cheat sheet is only intended for beginner-level pandas, this might be deemed too advanced, but it is necessary for this specific exam question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:32:24Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q20", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q20", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - lambda - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000\n\nYou want to create a new column called Bonus that compute each employee's bonus based on their salary and performance review using the following formula:\n- if the performance review is less than 4, the bonus is 0.\n- if the performance review is 4 or 5, the bonus is 5% of the salary.\n\nWhich of the following code snippets works as intended?", + "options": { + "a": "df['Bonus'] = df.apply(lambda row: row['Salary']*0.05 if row['Performance_review']>=4 else 0, axis=1)", + "b": "df['Bonus'] = df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>=4 else 0)", + "c": "df['Bonus'] = map(df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>4 else 0))", + "d": "df['Bonus'] = df['Salary'].map(lambda row: row*0.05 if df['Performance_review']>=4 else 0)" + }, + "correct": "a", + "explanation": "Option A evaluates each row, checks the row's Performance_review value, and returns either 5% of Salary or 0 for that employee.", + "code_context": "Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the fundamental syntax for creating a new column ('C') in a DataFrame from existing columns ('A' and 'B'), which helps a student understand the 'df['Bonus'] = ...' structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the fundamental syntax for creating a new column ('C') in a DataFrame from existing columns ('A' and 'B'), which helps a student understand the 'df['Bonus'] = ...' structure.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets cover basic column creation and the concept of mapping functions, they do not explain the 'axis=1' parameter or the specific 'lambda row' pattern required to access multiple columns at once. A student with zero prior knowledge would likely struggle to distinguish between using .apply() on the DataFrame vs. using .map() or .apply() on a single column.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no information explaining row-wise operations involving multiple columns, specifically the 'axis=1' parameter in .apply().", + "missing_concepts": [ + "df.apply(axis=1) for row-wise manipulation", + "Using lambda row to access multiple column values simultaneously", + "Difference between Series.map() and DataFrame.apply(axis=1)" + ], + "proposed_fix": "Add a snippet to Week 5 (Pandas) that explicitly shows how to calculate a new column based on conditions across two or more other columns using .apply(axis=1)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a piece to Topic: 'Working With Values' (Week 5): 'Row-wise Operations: To create a column based on values in multiple columns, use df.apply(lambda row: func(row[\"Col1\"], row[\"Col2\"]), axis=1). The axis=1 argument ensures the function sees each row as an object, allowing you to access any column inside the lambda.'", + "why_helpful": "This directly explains the 'axis=1' and 'lambda row' syntax which are the keys to identifying the correct answer in this common exam question pattern.", + "why_maybe_unnecessary": "Only if the curriculum expects students to intuit row-wise application from basic series mapping, which is highly unlikely for beginners.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:33:14Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q21", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q21", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_3", + "question": "You want to create a function called main which take an integer and a flexible number of strings as arguments. The strings represent dates in the format of DD MM YYYY. The day, month and year can be separated by different characters.\n\nYour function should look for the string inputs which represent dates as DD-MM-YYYY or DD/MM/YYYY and return those strings in the format of DD.MM.YYYY in a list. Furthermore, the dates represented by the strings should be shifted by the amount of days as given by the integer argument.\n\nFor example, if we call your function as:\nmain(3, '25/06/2003', '26.06.2003', '27-06-2003', '28:06:2023', '29-06-2023', '30.06.2023')\n\nthe output should be:\n['28.06.2003', '30.06.2003', '02.07.2023']\n\nTake a look at the following code segment. Does it do what is intended? If not, then why not?", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the function will return a list of datetime objects, not a list of strings representing dates.", + "c": "This code segment does not work because the strftime() method cannot be applied to NoneType object.", + "d": "This code segment produces an error because you cannot concatenate strings and timedelta." + }, + "correct": "b", + "explanation": "The function parses matching inputs and adds the day offset, but it appends datetime objects and never converts them back to strings in DD.MM.YYYY format before returning.", + "code_context": "def main(delta, *args):\n dates = []\n for string in args:\n if '-' in string:\n dates.append(datetime.strptime(string, '%d-%m-%Y') + timedelta(days=delta))\n elif '/' in string:\n dates.append(datetime.strptime(string, '%d/%m/%Y') + timedelta(days=delta))\n else:\n dates.append(None)\n return [date for date in dates if type(date) != None]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Provides a practical example of a function using *args to filter and process a flexible number of inputs, mirroring the structure of the exam question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "Provides a practical example of a function using *args to filter and process a flexible number of inputs, mirroring the structure of the exam question.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "medium", + "rationale": "The snippets explain function syntax and flexible arguments (*args), but there is zero information regarding the datetime module. A student with no prior knowledge wouldn't know that datetime.strptime returns an object or that timedelta addition results in another datetime object, which is the core of the question (distinguishing between objects and strings).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Complete absence of datetime module documentation or usage examples.", + "missing_concepts": [ + "datetime.strptime (parsing strings to datetime objects)", + "datetime.strftime (formatting datetime objects to strings)", + "timedelta (representing and adding time durations)", + "Difference between datetime objects and string representations of dates" + ], + "proposed_fix": "Add a new snippet or key point explaining the datetime module workflow: String -> strptime -> Object -> arithmetic with timedelta -> strftime -> String." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a Datetime Basics snippet: 'To process dates, use datetime.strptime(string, format) to create a datetime object. To go back to a string, use object.strftime(format). Use timedelta(days=n) to shift dates. strptime returns an object, not a string.'", + "why_helpful": "This directly enables the student to see that the provided code segment stops at the 'Object' phase and fails to perform the final 'strftime' conversion to strings required by the question.", + "why_maybe_unnecessary": "If the student somehow infers from the options that 'datetime objects' are a distinct type from strings, they might guess 'b', but they wouldn't know for sure.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:33:41Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ai-example-8", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually availabl" + }, + { + "item_id": "ai-example-5", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "import module does not create bare globals\nclear_names()\n\nfrom extension import create_absolute_year as cay\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(cay(1))\nexcept Exception as e:\n print(e)\nKeep track of which name is actually" + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import r" + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Direct import plus alias binds both names\nclear_names()\n\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ..." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q22", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q22", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_2", + "question": "You want to define a class called Calendar, which has four attributes that are initialized at the time of object construction:\n1. The 'event' attribute can be any string,\n2. The 'date' attribute is a string representing a date as 'DD-MM-YYYY',\n3. The 'start' attribute is a string representing the time as 'HH:MM', and\n4. The 'length' attribute is an integer representing the amount of minutes.\n\nThe class should also have a method called get_details() that gives a description of Calendar objects.\n\nFor example, if we execute the following commands;\nevent1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n\nthe output should be:\nCoffee meeting: 01-06-2023, 9:30-9:50.\n\nWhich of the following code segments gives you what you want?", + "options": { + "a": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day, int(start.split(':')[0]), int(start.split(':')[1]))\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "b": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.split(':')[0], minute=start.split(':')[1])\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "c": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.hour, minute=start.minute)\n self.end = self.self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "d": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start.hour = start.hour\n self.start.minute = start.minute\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'" + }, + "correct": "a", + "explanation": "Option A is the only choice that correctly parses the date string, combines the parsed date with the split start time to build a datetime, adds the duration in minutes, and formats the requested details string.", + "code_context": "event1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n# output:\n# Coffee meeting: 01-06-2023, 9:30-9:50." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the basic syntax for class definitions and the __init__ method which is required to evaluate the structure of the options." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows basic string formatting within a print/text context, which helps understanding the get_details() method structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the basic syntax for class definitions and the __init__ method which is required to evaluate the structure of the options.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows basic string formatting within a print/text context, which helps understanding the get_details() method structure.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets cover basic OOP and mention the existence of datetime/timedelta, they do not explain the strptime() and strftime() methods, nor how to instantiate a datetime object with specific hour/minute parameters or use split() on strings. A student with zero knowledge would not be able to confidently select Option A over the syntactically plausible but incorrect alternatives.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The provided snippets lack coverage of datetime string parsing and formatting, and basic string splitting.", + "missing_concepts": [ + "datetime.strptime()", + "datetime.strftime()", + "string.split()", + "timedelta(minutes=...)", + "datetime object attribute access (.hour, .minute)" + ], + "proposed_fix": "Add a snippet family for Datetime Manipulation that explicitly shows parsing strings into datetimes, formatting them back to strings, and performing arithmetic with specific timedelta units (minutes, hours)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: 'dt = datetime.strptime(\"01-01-2023\", \"%d-%m-%Y\")', 'new_dt = dt + timedelta(minutes=30)', and 'print(new_dt.strftime(\"%H:%M\"))'.", + "why_helpful": "This would directly address the core difficulty of the question: converting strings to datetime objects and performing duration math.", + "why_maybe_unnecessary": "If the course expects students to memorize these standard library methods, but for a 'zero knowledge' student, this is a hard requirement.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:34:26Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q23", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q23", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Function_2", + "question": "You have the following definition for a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nYou want to add three methods to this class:\n1. The holiday_bonus() method which computes and returns the holiday bonus, which is 8.0% of the yearly salary,\n2. The year_end_bonus() method which computes and returns the year end bonus, which is 8.3% of the yearly salary\n3. The payment_overview() method which returns a payment overview of the employee using the following format:\n[Name] receives $[salary] monthly, $[holiday bonus] in May and $[year end bonus] in December.\n\nFor example, if we execute the following commands:\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())\n\nthe output should be:\n2400.0\n2490.0\nJohn Smith receives $2500 monthly, $2400.0 in May and $2490.0 in December.\n\nWhich of the following code segments should you place on the blank in the class definition to achieve what you want?", + "options": { + "a": "def holiday_bonus(self):\n return self.salary * 12 * 0.080\ndef year_end_bonus(self):\n return self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus()} in May and ${self.year_end_bonus()} in December.'", + "b": "def payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.salary*12*0.08} in May and ${self.salary*12*0.083} in December.'", + "c": "def holiday_bonus():\n self.holiday_bonus = self.salary * 12 * 0.080\ndef year_end_bonus():\n self.year_end_bonus = self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'", + "d": "def payment_overview(self):\n self.holiday_bonus = self.salary * 12 * 0.080\n self.year_end_bonus = self.salary * 12 * 0.083\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'" + }, + "correct": "a", + "explanation": "Option A defines all three requested methods, computes the two bonuses from the yearly salary, and uses those method results in the overview string.", + "code_context": "class Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining a class and initializing attributes (name, mode), helping the student understand the 'self' syntax and attribute access used in the Employee class." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string formatting with variables and rounding, which is necessary for constructing the 'payment_overview' method return string." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining a class and initializing attributes (name, mode), helping the student understand the 'self' syntax and attribute access used in the Employee class.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string formatting with variables and rounding, which is necessary for constructing the 'payment_overview' method return string.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class structure, attribute access, and string formatting. However, they do not explicitly show a method calling another method within the same class using 'self.method()', which is the critical syntax required to distinguish Option A from the others. A student might not know if they should use parentheses or if variables like 'self.holiday_bonus' (Option C/D) are sufficient.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing a clear example of 'internal method delegation'—where one instance method calls another instance method of the same object.", + "missing_concepts": [ + "method-to-method calling syntax (self.method_name())", + "difference between instance attributes and instance methods" + ], + "proposed_fix": "Add an OOP snippet showing a class like 'Receipt' with a 'get_tax()' method and a 'get_total()' method that calls 'self.get_tax()'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet for OOP Methods showing: class Order: def get_tax(self): return self.price * 0.1; def get_total(self): return self.price + self.get_tax().", + "why_helpful": "This would directly demonstrate how to call one method from another using the self reference and parentheses, clarifying why Option A is correct over Options C and D.", + "why_maybe_unnecessary": "Basic OOP tutorials often cover this, but for a 'zero knowledge' cheat sheet, this specific delegation is a common stumbling block.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:34:58Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q24", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q24", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Hard_2", + "question": "You have the following definitions for a class called Car:\n\nclass Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nYou want to create another class called Garage, which has two attributes that are initialized during object construction:\n- The 'capacity' attribute, which is an integer and must be passed to the object constructor.\n- The 'cars' attribute, which is an empty list.\n\nThe Garage class should also have two methods:\n1. The add_car() method, which adds Car objects to a Garage object. New Car objects can only be added if there is still capacity in the Garage object. If not, the method should return \"Capacity reached.\"\n2. The check_garage() method, which reports the Car objects that have been added to the Garage object. The method should return a dictionary in which the keys are the counts of Car objects starting from 1 and the values are the Car objects' descriptions.\n\nFor example, if we execute the following commands:\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n\nthe output should be:\n{1: 'Toyota, Camry', 2: 'Honda, Accord'}\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "class Garage:\n def __init__(self, capacity, cars = []):\n self.capacity = capacity\n\n def add_car(self, car):\n self.cars += car if len(self.cars) < self.capacity else return 'Capacity reached.'\n\n def check_garage(self, car):\n return {index: car.get_description() for index, car in enumerate(self.cars, start=1)}", + "b": "class Garage:\n def __init__(self, capacity):\n self.capacity = capacity\n self.cars = []\n\n def add_car(self, car):\n if len(self.cars) < self.capacity:\n self.cars.append(car)\n else:\n return 'Capacity reached.'\n\n def check_garage(self):\n output = {}\n for index, car in enumerate(self.cars, start=1):\n output[index] = car.get_description()\n return output", + "c": "Both of the above will work.", + "d": "None of the above will work." + }, + "correct": "b", + "explanation": "Option B initializes capacity and an empty cars list, appends cars only when capacity remains, returns the required message when full, and builds the requested dictionary in check_garage().", + "code_context": "class Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n# output:\n# {1: 'Toyota, Camry', 2: 'Honda, Accord'}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates adding methods with internal logic and attribute comparisons to a class, helping the student understand how add_car() and check_garage() should be structured." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary with integer keys starting from 1, which matches the expected output format of the check_garage() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates adding methods with internal logic and attribute comparisons to a class, helping the student understand how add_car() and check_garage() should be structured.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary with integer keys starting from 1, which matches the expected output format of the check_garage() method.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class structure, method definitions, and the target dictionary format. However, they lack specific examples of using 'enumerate' with a 'start' parameter and the 'list.append()' method, making it difficult for a student with zero knowledge to confidently select Option B over the syntactically incorrect Option A.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets do not explain how to iterate with an index (enumerate) or how to properly add items to a list attribute (append).", + "missing_concepts": [ + "enumerate() with start parameter", + "list.append() method", + "list concatenation vs appending (+= vs .append)" + ], + "proposed_fix": "Add a snippet from Week 2 or Week 4 materials that explicitly shows list appending and the use of enumerate() to build a dictionary from a list." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet family 'Iteration and List Modification' featuring an example like: 'my_list = []; my_list.append(x); result = {i: val for i, val in enumerate(my_list, start=1)}'.", + "why_helpful": "This would directly address the two most specific technical requirements of the question: how to grow the list and how to generate the indexed dictionary.", + "why_maybe_unnecessary": "The student might infer list usage from prior general programming knowledge, but 'enumerate' is quite Python-specific.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:35:33Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q01", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q01", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_3", + "question": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?", + "options": { + "a": "if x in list(range(11))[::2]:\n print('Even number')\nelse:\n print('Odd number')", + "b": "if x % 2 != 0:\n print('Odd number')\nelse:\n print('Even number')", + "c": "if x in [1, 3, 5, 7, 9]:\n print('Odd number')\nelse:\n print('Even number')", + "d": "All of the programs work as intended." + }, + "correct": "d", + "explanation": "Option A checks membership in the even numbers from 0 through 10, option B checks oddness with modulo, and option C checks membership in the odd numbers from 1 through 9. All three correctly classify x as odd or even in the stated range.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the best general snippet as it explains list slicing with steps (e.g., [::2]), which is the most complex concept in Option A." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the best general snippet as it explains list slicing with steps (e.g., [::2]), which is the most complex concept in Option A." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Demonstrates the evaluation of boolean expressions and comparisons (True/False), which is necessary for understanding the logic in Options A, B, and C." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Provides the complete answer and explanation for the specific problem." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "This piece contains the exact question text, all four options, and the correct answer explanation, providing a direct solution." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the best general snippet as it explains list slicing with steps (e.g., [::2]), which is the most complex concept in Option A.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Demonstrates the evaluation of boolean expressions and comparisons (True/False), which is necessary for understanding the logic in Options A, B, and C.", + "critical_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Provides the complete answer and explanation for the specific problem.", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-1-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam question is present in the candidate list. Without it, the student would lack information on the modulo operator (%) and the range() function behavior.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the identical question provides the answer, the general knowledge snippets are missing basic arithmetic operators and sequence generation functions.", + "missing_concepts": [ + "Modulo operator (%) for parity checking", + "range() function behavior (start, stop, step)", + "List membership operator ('in')" + ], + "proposed_fix": "Add a foundational snippet covering basic Python operators (arithmetic and comparison) and another explaining the range() function." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Basic Operators' that explains: 1. Modulo (%) for finding remainders/parity. 2. Comparison operators (==, !=). 3. The 'in' operator for checking membership in lists.", + "why_helpful": "This would allow a student to solve Option B and C from first principles rather than relying on an identical past exam match.", + "why_maybe_unnecessary": "Not needed if the student only cares about matching the specific question to the past exam bank.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Sequences with range()' explaining that range(n) produces numbers from 0 to n-1.", + "why_helpful": "Essential for understanding why range(11) includes the number 10, which is crucial for Option A.", + "why_maybe_unnecessary": "The identical question explanation already mentions the range 0 through 10.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:36:25Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q02", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q02", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_2", + "question": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "options": { + "a": "This code will produce an error because a is a global name that is referenced inside the local scope of inner().", + "b": "This code will not produce any error and will return 30.", + "c": "This code will produce an error because c is not defined before referencing.", + "d": "This code will not produce any error and will return 50." + }, + "correct": "b", + "explanation": "The function inner receives c as its argument, so c is defined. It can also read the global a. inner(5) returns 1 + 5 + 4 = 10, and outer returns 10 * 3 = 30.", + "code_context": "a = 1\ndef outer(b):\n b = 3\n def inner(c):\n d = 4\n return a + c + d\n return inner(5) * b\nouter(5)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Provides the fundamental rules of Python scope (global vs local) needed to solve the problem from first principles without relying on the exact past exam match." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the fundamental rules of Python scope (global vs local) needed to solve the problem from first principles without relying on the exact past exam match." + }, + { + "item_id": "exam-extra_practice-2-w3-scope", + "rationale": "Demonstrates a concrete example of global and local variables with the same name, reinforcing the 'local dominates' and accessibility rules." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-2-w3-scope", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "rationale": "This piece contains the exact same question, code context, and explanation as the provided question JSON." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "Provides the fundamental rules of Python scope (global vs local) needed to solve the problem from first principles without relying on the exact past exam match.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "rationale": "Demonstrates a concrete example of global and local variables with the same name, reinforcing the 'local dominates' and accessibility rules.", + "critical_piece_ids": [ + "exam-extra_practice-2-w3-scope" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-2-w3-scope" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The lecture snippet explicitly states that global names are known everywhere except when a same-named local exists. This confirms 'a' is accessible. The code evaluation requires basic arithmetic (1+5+4=10, 10*3=30) which is straightforward once the scope error is debunked.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the scope rules are clear, a student might still be confused by nested function definitions or the exact syntax of returning a function call result.", + "missing_concepts": [ + "Nested function definition behavior", + "Function argument passing (c receives 5)" + ], + "proposed_fix": "Add a snippet or piece that explicitly shows a nested function accessing variables from the enclosing function's scope." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:36:50Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?\na\nb\nc\nd\nb\nThe global variable 'a' is accessible inside the inner function without error. The code evaluates to inner(5) * 3 = (1 + 5 + 4) * 3 = 30." + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Corre" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-extra_practice-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modif" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q03", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q03", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_2", + "question": "What will be returned by the following code segment?", + "options": { + "a": "[0, None, 2, 3, None, 5, 6, 7, 8, None]", + "b": "[0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, 9]", + "c": "[None, 1.0, None, None, 3.5, None, None, None, None, '9']", + "d": "[0, None, 2, 3, None, 5, 6, 7, 8, 9]" + }, + "correct": "a", + "explanation": "The function appends each item if its exact type is int; otherwise it appends None. In the given list, 1.0, 3.50, and '9' are not ints, so those positions become None.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n if type(item) == int:\n list_2.append(item)\n else:\n list_2.append(None)\n return list_2\n\nmain([0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, '9'])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet provides a comprehensive breakdown of Python types, explicitly labeling 'abc' as str, 0 as int, and 123.456 as float, which is essential for distinguishing types in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet provides a comprehensive breakdown of Python types, explicitly labeling 'abc' as str, 0 as int, and 123.456 as float, which is essential for distinguishing types in the question." + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Shows how the type() function is used inside a loop to compare elements against a specific type, paralleling the question's structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "This snippet contains the exact logic and values (1.0, 3.50, '9') used in the question, explicitly explaining that they are not 'int' and thus return 'None'." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet provides a comprehensive breakdown of Python types, explicitly labeling 'abc' as str, 0 as int, and 123.456 as float, which is essential for distinguishing types in the question.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Shows how the type() function is used inside a loop to compare elements against a specific type, paralleling the question's structure.", + "critical_piece_ids": [ + "exam-Resit 22/23-3-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes an identical past exam question. Even without it, the general type knowledge snippet would allow a student to identify which elements in the list are not integers.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent due to the presence of an identical question and high-quality general type definitions.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:37:29Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q04", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q04", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 2", + "question": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}", + "b": "roman_nums = {roman: num for roman, num in zip(['I', 'II', 'III', 'IV', 'V'], range(1, 6))}", + "c": "roman_nums = {num: ['I', 'II', 'III', 'IV', 'V'][num] for num in range(1, 6)}", + "d": "roman_nums = {num: roman for num, roman in zip(range(1, 6), 'I II III IV V')}" + }, + "correct": "a", + "explanation": "Option A zips the integers 1 through 5 with the five Roman numeral strings and builds the required dictionary. The other options either reverse the keys and values, use incorrect indexing, or iterate over a plain string instead of the intended list of numerals.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows the scenario of creating a dictionary from two parallel lists (names and ages), which is the primary use case for the zip() function used in the correct answer." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Another example of mapping keys to specific values (vowels to ASCII), helping the student recognize the pattern of building a mapping dictionary." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "This is the exact same question about creating the roman_nums dictionary using Roman numerals 1-5." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows the scenario of creating a dictionary from two parallel lists (names and ages), which is the primary use case for the zip() function used in the correct answer.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Another example of mapping keys to specific values (vowels to ASCII), helping the student recognize the pattern of building a mapping dictionary.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the near-identical snippet provides the answer directly, the remaining candidate snippets only describe the logic of mapping lists to dictionaries without showing the actual Python implementation (zip, range, or comprehension syntax) in the search text. A student with zero knowledge would find it difficult to distinguish between the correct zip() usage and the incorrect string iteration in Option D.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate list is heavily reliant on past exam questions rather than syntax references. There is no piece explaining how zip() pairs items or that range(1, 6) excludes the number 6.", + "missing_concepts": [ + "zip() function mechanics (pairing elements from two iterables)", + "Dictionary comprehension syntax {k: v for ...}", + "range(start, stop) behavior (the stop value is exclusive)", + "Difference between iterating over a list vs. a space-separated string" + ], + "proposed_fix": "Add a general reference snippet for 'Dictionary Comprehensions' and 'Common Iteration Utilities' that explicitly shows the syntax and examples of zip() and range()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new 'Dictionary Comprehensions & Utilities' reference piece. It should define the syntax {key_expr: val_expr for item in iterable} and provide a clear example: `my_dict = {k: v for k, v in zip(['a', 'b'], [1, 2])}`. Also include a note that range(1, 6) produces numbers 1 to 5.", + "why_helpful": "This would bridge the gap from knowing 'what' needs to be done (mapping numbers to numerals) to 'how' it is written in Python, making the question answerable without relying on finding an identical past question.", + "why_maybe_unnecessary": "If the cheat sheet's primary purpose is to provide past exam answers, the near-identical piece already covers this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:38:02Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q05", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q05", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 2", + "question": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to only include the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[name] = age", + "b": "person_dict = {}\nfor i, name in enumerate(names):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[i] = ages[i]", + "c": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict.append(name:age)", + "d": "person_dict = {}\nfor i, name in enumerate(names):\n for j, letter in enumerate(name):\n if letter == 'A' or letter == 'C':\n person_dict[i] = ages[j]" + }, + "correct": "a", + "explanation": "Option A correctly iterates over names and ages together and stores only the names beginning with A or C as keys mapped to their ages. The other options use indices as keys, invalid dictionary syntax, or incorrect nested-loop logic.", + "code_context": "names = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Excluding the identical match, this is the best general snippet because it demonstrates creating a dictionary from a list where the keys are the list items and values are computed from them, matching the basic loop-and-assign pattern." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Excluding the identical match, this is the best general snippet because it demonstrates creating a dictionary from a list where the keys are the list items and values are computed from them, matching the basic loop-and-assign pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the fundamental syntax for creating a dictionary (roman_nums) and mapping keys to values using the bracket notation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This piece contains the exact same scenario (names and ages lists) and goal (person_dict with 'A' or 'C' filter) as the current question." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Excluding the identical match, this is the best general snippet because it demonstrates creating a dictionary from a list where the keys are the list items and values are computed from them, matching the basic loop-and-assign pattern.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the fundamental syntax for creating a dictionary (roman_nums) and mapping keys to values using the bracket notation.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam piece provides the exact solution. Even without it, the Resit piece shows the dictionary assignment pattern d[key] = value, though the student would still need to figure out zip() and string indexing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While dictionary assignment is covered, the specific use of zip() to iterate over two lists simultaneously is not explicitly explained in the general snippets provided.", + "missing_concepts": [ + "zip() function for parallel iteration", + "string indexing (e.g., name[0])" + ], + "proposed_fix": "Add a snippet or detail explaining how to use zip() to pair items from two lists for dictionary creation." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Construction from Lists' snippet that explicitly shows: 1. Initialization (d = {}), 2. zip(listA, listB) usage, 3. Conditional filtering, 4. Assignment (d[k] = v).", + "why_helpful": "This would allow a student to solve this question and similar 'convert two lists to a filtered map' problems without relying on finding a verbatim past exam question.", + "why_maybe_unnecessary": "The 'Resit 22/23-7' snippet already teaches the dictionary assignment pattern, which is the most critical syntax gap.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:38:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q06", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q06", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 2", + "question": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?", + "options": { + "a": "max_rating = max(employee_ratings.values())\nfor employee, rating in employee_ratings.items():\n if rating == max_rating:\n print(employee)", + "b": "max_rating_employee = max(employee_ratings.keys())\nfor employee, rating in employee_ratings.items():\n if employee == max_rating_employee:\n print(employee)", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "a", + "explanation": "Option A correctly computes the maximum rating value and prints every employee whose rating matches it. Option B instead finds the maximum key lexicographically, not the employee with the highest rating.", + "code_context": "employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This is the best general snippet as it demonstrates the exact pattern required: iterating over dictionary items using '.items()', checking a value condition (above average), and printing the corresponding keys (names)." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This is the best general snippet as it demonstrates the exact pattern required: iterating over dictionary items using '.items()', checking a value condition (above average), and printing the corresponding keys (names)." + }, + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "rationale": "Mentions creating a dictionary with 'highest and low' keys, which reinforces the concept of looking for extremas in dictionary values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text and context, including the employee_ratings dictionary and the goal of finding the highest performance rating." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This is the best general snippet as it demonstrates the exact pattern required: iterating over dictionary items using '.items()', checking a value condition (above average), and printing the corresponding keys (names).", + "critical_piece_ids": [ + "exam-extra_practice-4-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "rationale": "Mentions creating a dictionary with 'highest and low' keys, which reinforces the concept of looking for extremas in dictionary values.", + "critical_piece_ids": [ + "exam-extra_practice-3-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-4-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question is present in the near-identical pieces. Furthermore, the 'extra_practice-4' snippet provides a clear template for the iteration and conditional printing logic needed to evaluate the code options.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic of iteration is covered, there is no general snippet that explicitly explains the difference between 'dict.keys()' and 'dict.values()' or how 'max()' behaves when applied to them.", + "missing_concepts": [ + "dictionary.values() vs dictionary.keys()", + "max() behavior on dictionary views" + ], + "proposed_fix": "Add a conceptual snippet or piece that explains dictionary methods (.keys(), .values(), .items()) and their interaction with built-in functions like max()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Dictionary Methods and Max/Min' that shows: 1) d.keys() returns names, 2) d.values() returns scores/ratings, 3) max(d.values()) finds the highest score, while max(d.keys()) finds the 'alphabetically last' name.", + "why_helpful": "This would allow a student to solve the problem logically (comparing options A and B) even without seeing the exact past exam question.", + "why_maybe_unnecessary": "The 'extra_practice-4' snippet already shows the '.items()' iteration which is the core of the loop, and students might infer value-based maxing from the context.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:38:47Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nsample_dict = {\n\"name\": \"Kim\",\n\"age\": 25,\n\"birthdate\": \"3-2-1998\",\n\"city\": \"Amsterdam\"}\nSuppose you want to create a dictionary that only contains the keys 'name' and 'city'.\nWhich of the following code snippets return(s) the desired dic" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q07", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q07", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[2, 4]", + "b": "[3, 4, 5]", + "c": "[4]", + "d": "[]" + }, + "correct": "c", + "explanation": "The list comprehension keeps values x from [1, 2, 3, 4, 5] only when x is even and greater than 2. The only value satisfying both conditions is 4.", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x for x in numbers if x % 2 == 0 and x > 2]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Briefly mentions the logic of finding 'even numbers', which helps decode the `x % 2 == 0` part of the code segment." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This piece is an exact match for the question, providing the same code logic (filtering even numbers > 2) and the correct output '4'." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Briefly mentions the logic of finding 'even numbers', which helps decode the `x % 2 == 0` part of the code segment.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the near-identical piece, there is no explanation of the specific Python 'list comprehension' syntax `[expression for item in iterable if condition]`. A student with zero knowledge would find the compact notation in the code context unintelligible based solely on the general snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a definition or syntax guide for list comprehensions and the modulo operator.", + "missing_concepts": [ + "list comprehension syntax", + "modulo operator (%)", + "Python logical 'and' in comprehensions" + ], + "proposed_fix": "Add a general-purpose snippet explaining list comprehension structure and common filtering patterns (like even/odd checks)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a core concept snippet for 'List Comprehensions' that breaks down the syntax `[x for x in numbers if x > 2]` and explicitly defines `% 2 == 0` as the standard way to check for even numbers.", + "why_helpful": "This bridges the gap for a student who knows basic logic but doesn't recognize Python's specific shorthand for creating filtered lists.", + "why_maybe_unnecessary": "Students might learn this specific syntax through rote memorization of past exam answers if the question bank is small.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:39:23Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q08", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q08", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "['a', 'bb', 'ccc']", + "b": "[1, 2, 3]", + "c": "[1, 'b', 3]", + "d": "['aa', 'bb', 'cc']" + }, + "correct": "a", + "explanation": "The loop iterates over pairs from zip(list1, list2) and multiplies each string by its matching integer, producing 'a', 'bb', and 'ccc'.", + "code_context": "list1 = [1, 2, 3]\nlist2 = ['a', 'b', 'c']\nresult = []\nfor item in zip(list1, list2):\n result.append(item[0] * item[1])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code." + }, + { + "item_id": "aiq-2", + "rationale": "Provides examples of various list methods and operations, helping the student understand list-based logic, though it lacks the specific 'zip' and 'string multiplication' concepts." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "aiq-2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "Provides examples of various list methods and operations, helping the student understand list-based logic, though it lacks the specific 'zip' and 'string multiplication' concepts.", + "critical_piece_ids": [ + "aiq-2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While 'append' is covered, the core of the problem relies on two concepts completely missing from the candidates: 1) The zip() function pairing elements of lists together, and 2) String multiplication (e.g., 'a' * 2 = 'aa'). Without these, a student cannot determine the contents of the result list.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing definitions for 'zip' and the behavior of the multiplication operator between integers and strings.", + "missing_concepts": [ + "zip() function pairing", + "String-integer multiplication (repetition)", + "Tuple/item indexing inside a loop" + ], + "proposed_fix": "Add a new snippet explaining zip(listA, listB) and a note that 'abc' * 2 results in 'abcabc'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for 'Zip and Pairing': 'zip(list1, list2) combines lists into pairs: e.g., zip([1, 2], ['a', 'b']) -> (1, 'a'), (2, 'b')'.", + "why_helpful": "Essential for decoding the 'for item in zip(...)' loop and accessing indices item[0] and item[1].", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for 'String Multiplication': 'Multiplying a string by an integer repeats it: \"a\" * 3 -> \"aaa\"'.", + "why_helpful": "Required to understand the calculation 'item[0] * item[1]' where one is an int and the other a string.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:39:51Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q09", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q09", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 1", + "question": "Suppose you have a list called mylist. You want to extract every fourth element starting from index 2 (inclusive) to the second-to-last index (inclusive) of that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45, 50]\n\nthen executing the following command:\nprint(subset)\n\nshould print:\n[20, 35]\n\nWhat should the blanks be filled with?", + "options": { + "a": "2:-1:3", + "b": "2:len(mylist)-1:3", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "c", + "explanation": "Both stop values exclude the last element while starting at index 2 and stepping by 3, so both expressions return [20, 35] for the example list.", + "code_context": "subset = mylist[___:___:___]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Mentions operations on a 'list called x', which provides some context for list-based exam questions, though it does not cover slicing." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Mentions operations on a 'list called x', which provides some context for list-based exam questions, though it does not cover slicing.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While one snippet shows the `[start:stop:step]` syntax, it does not explain that the 'stop' index is exclusive, nor does it explain negative indexing (e.g., `-1`) or the `len()` function's role in indexing. A student with zero prior knowledge could not distinguish between options (a), (b), and (c) based on these snippets alone.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The available snippets show the slicing syntax but omit the semantic rules required to solve the problem.", + "missing_concepts": [ + "exclusive stop index in slicing", + "negative indexing (specifically -1 as the last element)", + "relationship between len(list) and the last index", + "slicing step logic (Nth element vs step N-1)" + ], + "proposed_fix": "Add a foundational snippet about Python list slicing that explicitly defines the inclusive start, exclusive stop, and the behavior of the step parameter, including negative indices." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'List Slicing Fundamentals' that explains `my_list[start:stop:step]`. It should state: 1) 'start' is the first index included. 2) 'stop' is the index where the slice ends (the element at 'stop' is NOT included). 3) '-1' refers to the last element. 4) 'len(my_list)' is the total count, so 'len(my_list)-1' is the index of the last element.", + "why_helpful": "This would directly allow a student to evaluate why both `-1` and `len(mylist)-1` effectively exclude the last element and satisfy the 'second-to-last index inclusive' requirement.", + "why_maybe_unnecessary": "If the student already understands standard range-based indexing from other languages, they might guess, but Python's negative indexing is unique enough to require a snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:40:37Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q10", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q10", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_2", + "question": "Suppose you have the following function, which takes a list of integers as an argument:\n\nWhat will be returned, if we call the function as follows:\nmain([0, 1, 2, 23, 24, 25])", + "options": { + "a": "'abcxyz'", + "b": "['a', 'b', 'c', 'x', 'y', 'z']", + "c": "'012232425'", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "The function walks through the alphabet with enumerate and appends each character whose index is present in the input list, giving a, b, c, x, y, and z.", + "code_context": "def main(x):\n alphabet = 'abcdefghijklmnopqrstuvwxyz'\n y = ''\n for index, character in enumerate(alphabet):\n if index in x:\n y += character\n return y" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic." + }, + { + "item_id": "aiq-4", + "rationale": "Contains pieces on 'Return Behavior', which is essential for understanding that the function results in a single value rather than a side effect like printing." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Establishes the context of the alphabet string." + }, + { + "item_id": "aiq-4", + "rationale": "Explains foundational return value mechanics." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "Contains pieces on 'Return Behavior', which is essential for understanding that the function results in a single value rather than a side effect like printing.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Establishes the context of the alphabet string.", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Explains foundational return value mechanics.", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The question's solution relies entirely on knowing that 'enumerate(alphabet)' yields pairs of (index, character). Without a snippet explaining that 'index' represents the numeric position (starting at 0), a student with zero prior knowledge cannot definitively solve the problem, as they wouldn't know if 'index' refers to the position or something else.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no explanation of the 'enumerate' function or the concept of retrieving an index during a loop iteration.", + "missing_concepts": [ + "enumerate() function", + "unpacking (index, value) in for loops", + "zero-based indexing" + ], + "proposed_fix": "Add a snippet explaining 'enumerate(sequence)': 'The enumerate() function allows you to loop through a sequence and have an automatic counter (index). Example: for i, val in enumerate([\"A\", \"B\"]): yields (0, \"A\") then (1, \"B\").'" + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet for the 'enumerate' function: 'The enumerate() function adds a counter to an iterable and returns it in a form of enumerate object. This object can then be used directly in for loops to get both the index and the value of each item. Example: for index, value in enumerate(\"cat\"): index 0 is \"c\", 1 is \"a\", 2 is \"t\".'", + "why_helpful": "This provides the missing technical link needed to interpret the loop in the question correctly.", + "why_maybe_unnecessary": "A student might guess that 'index' means position, but 'enumerate' is a specific Python keyword that needs explicit definition for zero-knowledge users.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:41:48Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q11", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q11", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_1", + "question": "Suppose you have a variable called x which contains a string as follows:\n\nx = 'Hello world'\n\nWhich of the following lines of code produce(s) 2 as an output?", + "options": { + "a": "print(x.count('o'))", + "b": "print(x.split(' ')[0].count('ll'))", + "c": "print(len(x)//5)", + "d": "All of the given options." + }, + "correct": "d", + "explanation": "The rendered solution page marks option D, indicating that the exam intends all three listed expressions to produce 2 for the given value of x.", + "code_context": "x = 'Hello world'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Shows a multiple-choice question structure where several expressions evaluate to the same result (True), leading to 'all lines' being correct, similar to the logic in the current question's Option D." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of string slicing and list conversion, which familiarizes the student with string-to-sequence operations like the .split() method in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question.", + "critical_piece_ids": [ + "exam-trial_midterm-19-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Shows a multiple-choice question structure where several expressions evaluate to the same result (True), leading to 'all lines' being correct, similar to the logic in the current question's Option D.", + "critical_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of string slicing and list conversion, which familiarizes the student with string-to-sequence operations like the .split() method in the question.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial_midterm-19-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The candidate snippets are all past exam questions rather than documentation. None of them define the specific methods (.count, .split), the built-in function (len), or the floor division operator (//) required to verify the arithmetic in the options. A student with zero prior knowledge could not conclude that len('Hello world') // 5 equals 2 without knowing what len or // do.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to provide definitions for core string methods and basic Python operators used in the question.", + "missing_concepts": [ + "str.count()", + "str.split()", + "len() function", + "// (floor division operator)" + ], + "proposed_fix": "Add a foundational card covering 'Basic String Methods and Operators' that explicitly defines len(), .count(), .split(), and arithmetic operators like // and %." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card titled 'Strings & Arithmetic Basics' including: 1. len(x): returns number of characters. 2. x.count('a'): returns occurrences of 'a'. 3. x.split(' '): breaks string into a list by space. 4. a // b: floor division (e.g., 11 // 5 = 2).", + "why_helpful": "This directly enables a student with zero knowledge to calculate the values for options A, B, and C.", + "why_maybe_unnecessary": "If the goal is only to provide past exam context, but in that case, the student remains unable to solve this specific problem.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:42:33Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q12", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q12", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_2", + "question": "You need to write a function called main which accepts a list of integers as an argument. The function should return a tuple of two integers, in which the first is the sum of the squares of all even numbers, and the second is the sum of the squares of all odd numbers.\n\nFor example, calling the function as:\nmain(1, 2, 3, 4)\nshould return:\n(20, 10)\n\nWhich of the following blocks of code fits with the rest of the program and will you give the intended output?", + "options": { + "a": "for i in args:\n if i % 2 == 0:\n total_even += i**2\n else:\n total_odd += i**2\n\nreturn (total_even, total_odd)", + "b": "for i in args:\n if i % 2 == 1:\n total_even += i\n else:\n total_odd += i\n\nreturn (total_even**2, total_odd**2)", + "c": "for i in args:\n if i % 2 == 0:\n total_even.append(i**2)\n else:\n total_odd.append(i**2)\n\nreturn (sum(total_even), sum(total_odd))", + "d": "All of the given code blocks work as intended." + }, + "correct": "a", + "explanation": "Option A directly accumulates the squares of even numbers and odd numbers into the two totals and returns them as the required tuple.", + "code_context": "def main(*args):\n total_even = 0\n total_odd = 0\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Specifically mentions a function (sum_even_integers) that accepts flexible arguments and performs parity filtering, directly mapping to the question's logic." + }, + { + "item_id": "aiq-5", + "rationale": "Contains a reminder about tuple syntax, helping the student recognize that (total_even, total_odd) is a valid tuple return." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + }, + { + "item_id": "aiq-5", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "Specifically mentions a function (sum_even_integers) that accepts flexible arguments and performs parity filtering, directly mapping to the question's logic.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:aiq-5", + "rationale": "Contains a reminder about tuple syntax, helping the student recognize that (total_even, total_odd) is a valid tuple return.", + "critical_piece_ids": [ + "aiq-5" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the framework for flexible arguments (*args), iteration, and tuple returns. However, the student still needs to know the specific syntax for modulo (%) to check even/odd status and exponentiation (**) for squaring, which are not explicitly in these snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing explicit demonstration of basic Python arithmetic operators for parity checks and power calculations.", + "missing_concepts": [ + "modulo operator (%) for parity checks", + "exponentiation operator (**) for squaring" + ], + "proposed_fix": "Add a snippet or key point covering arithmetic operators, specifically highlighting how to use % 2 to identify even/odd numbers and ** 2 to square values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Python Arithmetic Operators: Use `n % 2 == 0` to check if a number is even, and `n % 2 != 0` for odd. Use `n ** 2` to calculate the square of n.", + "why_helpful": "These operators are essential for the logic required in Option A but are not covered in the provided high-level function snippets.", + "why_maybe_unnecessary": "Students might have these concepts from earlier foundational weeks (Week 1 math) not represented in this subset.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:43:04Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 34, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "Slicing negative step\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.\nSlicing negative step" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ai-example-8", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95" + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller." + }, + { + "item_id": "ai-example-3", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "from-import binds only the imported name\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `im" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually availabl" + }, + { + "item_id": "kp-1", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import r" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q13", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q13", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 1", + "question": "You have the following objects loaded in Python:\nname = \"Alice\"\nage = 25\ncountry = \"the USA\"\n\nYou need to print the following string:\nMy name is Alice. I am 25 years old, and I am from the USA.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"My name is {0}. I am {2} years old, and I am from {1}.\".format(name, country, age)\nprint(message)", + "b": "message = f\"My name is {name}. I am {age} years old, and I am from {country}.\"\nprint(message)", + "c": "message = 'My name is ' + name + '. I am ' + str(age) + ' years old, and I am from ' + str(country) + '.'\nprint(message)", + "d": "All of the given options are correct." + }, + "correct": "d", + "explanation": "All three code variants produce the target sentence: one uses format, one uses an f-string, and one uses string concatenation with str(age) and str(country).", + "code_context": "name = \"Alice\"\nage = 25\ncountry = \"the USA\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "This snippet establishes that names are strings, which helps a student identify the data types being manipulated in the question, though it doesn't help with the formatting syntax." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "This snippet establishes that names are strings, which helps a student identify the data types being manipulated in the question, though it doesn't help with the formatting syntax.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets demonstrate the syntax for f-strings, the .format() method, or string concatenation with type conversion (str()). The snippets are almost entirely focused on dictionaries and data structures (Week 2), while this question tests Week 1 string formatting fundamentals.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippet database is missing fundamental content on string formatting and manipulation.", + "missing_concepts": [ + "f-strings (syntax: f'...')", + "str.format() method (including positional indices like {0}, {1})", + "string concatenation (+) and the requirement to use str() for non-string objects" + ], + "proposed_fix": "Add a dedicated snippet family for 'String Formatting' that explicitly shows examples of f-strings, .format(), and concatenation side-by-side." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet: 'Python String Formatting Methods'. It should include: 1. f-strings: f\"My name is {name}\"; 2. .format(): \"My name is {0}\".format(name); 3. Concatenation: \"My name is \" + name + \" and I am \" + str(age) + \" years old\".", + "why_helpful": "This would directly allow a student with zero knowledge to compare the options in the question to the provided syntax examples.", + "why_maybe_unnecessary": "Only unnecessary if such a snippet already exists under a different topic that wasn't included in the candidates.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:44:35Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q14", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q14", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 2", + "question": "Suppose you have the following DataFrame called df, and assume that pandas is already imported:\n\n Player Goals Assists\n0 John 5 2\n1 Jane 3 6\n2 Alex 2 4\n\nAll of the following lines of code make the same selection, but one of the results has a different datatype. Which one?", + "options": { + "a": "df.loc[:, 'Goals']", + "b": "df['Goals']", + "c": "df.loc[[0, 1, 2], 'Goals']", + "d": "df.loc[:, ['Goals']]" + }, + "correct": "d", + "explanation": "The first three expressions return a Series, while selecting with a list of column names returns a one-column DataFrame instead.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows a standard DataFrame with columns 'A' and 'B', helping the student visualize the structure mentioned in the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions a 'pandas Series', which is one of the datatypes involved in the question options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows a standard DataFrame with columns 'A' and 'B', helping the student visualize the structure mentioned in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions a 'pandas Series', which is one of the datatypes involved in the question options.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the crucial difference between selecting a column as a scalar (returning a Series) vs. selecting with a list (returning a DataFrame). The snippets show DataFrame usage but not the specific syntax/datatype rules required to answer 'Which one has a different datatype?'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets identify pandas structures but fail to provide the rules for selection return types.", + "missing_concepts": [ + "Difference between Series and DataFrame return types in pandas selection", + "Behavior of .loc when passed a single label vs a list of labels", + "The use of double brackets [[]] vs single brackets [] for column selection" + ], + "proposed_fix": "Add a summary item or a detailed lecture snippet that explicitly states: 'Selecting with a single label (df['A'] or df.loc[:, 'A']) returns a Series, while selecting with a list of labels (df[['A']] or df.loc[:, ['A']]) returns a DataFrame.'" + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point or cheat sheet item: 'Pandas Selection Types: df['col'] or df.loc[:, 'col'] returns a Series (1D). df[['col']] or df.loc[:, ['col']] returns a DataFrame (2D). Passing a list to .loc always forces a DataFrame result even for a single column.'", + "why_helpful": "This directly addresses the 'different datatype' logic required by the question.", + "why_maybe_unnecessary": "If the user only wants past exam questions as snippets, this would need to be synthesized from a lecture.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:45:20Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q15", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q15", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_3", + "question": "Which code segment gives the same output as the following:\n\ndate1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module.", + "options": { + "a": "print((datetime(2023, 5, 1) - datetime(2023, 6, 1)).days)", + "b": "print((datetime(2023, 6, 1) - datetime(2023, 1, 5)).days)", + "c": "print((datetime.strptime('2023-6-1', '%Y-%d-%m') - datetime.strptime('2023-5-1', '%Y-%d-%m')).days)", + "d": "print((datetime.strptime('2023-06-01', '%Y-%m-%d') - datetime.strptime('2023-05-01', '%Y-%m-%d')).days)" + }, + "correct": "d", + "explanation": "Option D parses ISO-style date strings using the matching '%Y-%m-%d' format and subtracts the May date from the June date, giving the same day difference as the original code.", + "code_context": "date1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Provides a very basic introduction to functions, which helps a novice understand that methods like strftime and strptime are groupings of code performing tasks." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Provides a very basic introduction to functions, which helps a novice understand that methods like strftime and strptime are groupings of code performing tasks.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "low", + "rationale": "The available snippets explain the result of datetime subtraction and the .days attribute, but they completely lack information on strftime, strptime, and the specific formatting codes (like %d, %m, %Y) used in both the question and the options. A student without prior knowledge would be guessing the meaning of the date strings and parsing logic.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The main gap is the lack of documentation on date string parsing and formatting.", + "missing_concepts": [ + "datetime.strptime", + "datetime.strftime", + "strftime/strptime format codes (%Y, %m, %d, %H, etc.)" + ], + "proposed_fix": "Add a lecture-style snippet or a comprehensive 'cheat sheet' piece that lists common datetime formatting codes and explains the difference between creating a string (strftime) and parsing a string (strptime)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Datetime Formatting Reference' piece from the Week 6 lecture materials. It should include: 1. datetime.strftime(format) for object -> string. 2. datetime.strptime(string, format) for string -> object. 3. A table of common codes: %Y (year), %m (month), %d (day), %H (hour), %M (minute).", + "why_helpful": "This would allow a student to decode the '1-6-2023' vs '2023-06-01' logic and verify which format string matches the date representation.", + "why_maybe_unnecessary": "If the exam is open-book and students are expected to use a general Python reference, but for a 'cheat sheet' generator, this is a core missing component.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:46:02Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
          • A function is a grouping of code that can perform a certain task and can be re-used \n
          • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q16", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q16", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Easy_2", + "question": "You have the following definition of a class called Flight. What would be the output if we execute the following statements?", + "options": { + "a": "'long'\n'cheap'", + "b": "'short'\n'expensive'", + "c": "'long'\n'expensive'", + "d": "'short'\n'cheap'" + }, + "correct": "a", + "explanation": "The first condition sets the KLM flight to Singapore to duration 'long', and the second condition sets the EasyJet flight to Spain to price 'cheap', so the two prints output 'long' and then 'cheap'.", + "code_context": "class Flight:\n def __init__(self, airline, destination):\n self.airline = airline\n self.destination = destination\n\n if self.airline == 'KLM' and self.destination == 'Singapore':\n self.duration = 'long'\n self.price = 'expensive'\n\n if self.airline == 'EasyJet' and self.destination == 'Spain':\n self.duration = 'short'\n self.price = 'cheap'\n\nprint(Flight('KLM', 'Singapore').duration)\nprint(Flight('EasyJet', 'Spain').price)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-06b21ad349", + "rationale": "This lecture snippet explicitly defines the __init__ method as the constructor called automatically to initialize attributes. It provides the most direct conceptual bridge for a student to understand how arguments passed to Flight() end up as attributes on 'self'." + }, + "top_three_snippets": [ + { + "item_id": "ks-06b21ad349", + "rationale": "This lecture snippet explicitly defines the __init__ method as the constructor called automatically to initialize attributes. It provides the most direct conceptual bridge for a student to understand how arguments passed to Flight() end up as attributes on 'self'." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows a similar pattern of defining a class (Vehicle) with attributes (name, mode) that are initialized at the time of object construction, reinforcing the pattern seen in the Flight class." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-06b21ad349", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:ks-06b21ad349", + "rationale": "This lecture snippet explicitly defines the __init__ method as the constructor called automatically to initialize attributes. It provides the most direct conceptual bridge for a student to understand how arguments passed to Flight() end up as attributes on 'self'.", + "critical_piece_ids": [ + "ks-06b21ad349" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows a similar pattern of defining a class (Vehicle) with attributes (name, mode) that are initialized at the time of object construction, reinforcing the pattern seen in the Flight class.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-06b21ad349", + "rationale": "", + "needed_piece_ids": [ + "ks-06b21ad349" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The question relies on understanding that Flight('KLM', 'Singapore') triggers the __init__ method. Once the student knows that 'self.airline' becomes 'KLM' and 'self.destination' becomes 'Singapore', the 'if' and 'and' logic is readable as plain English. The lecture snippet ks-06b21ad349 provides exactly this explanation.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets explain how attributes are defined within the class using 'self', but they do not explicitly demonstrate the 'dot notation' used to access those attributes from outside the class (e.g., .duration).", + "missing_concepts": [ + "attribute access syntax (dot notation)" + ], + "proposed_fix": "Update the Car example in ks-06b21ad349 to show an instance being created and its attribute being printed." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-06b21ad349", + "proposal": "Extend the code example: \nclass Car:\n def __init__(self, color):\n self.color = color\n\nmy_car = Car('red')\nprint(my_car.color) # Accessing the attribute", + "why_helpful": "It shows the full lifecycle: definition, initialization, and retrieval (which is what the exam question asks for).", + "why_maybe_unnecessary": "Dot notation for 'properties' is often intuitive for students even without prior coding experience.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:46:49Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:ks-06b21ad349", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ks-06b21ad349", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Class Definition and __init__\nA class is a blueprint. The __init__ method is the constructor called automatically when a new object is created to initialize attributes.\nDefining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q17", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q17", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "6-string - operations - 1", + "question": "Consider the following code snippet. Which operation in the code snippet contains an error?", + "options": { + "a": "Operation 1", + "b": "Operation 2", + "c": "Operation 3", + "d": "None of the operations contains an error." + }, + "correct": "b", + "explanation": "Operation 2 is incorrect because join should be called as the separator string's method with a single iterable argument, for example '-'.join(word_list).", + "code_context": "text = \"The universe is vast and full of mysteries!\"\n\n# Operation 1:\nword_list = []\nfor word in text.split():\n word_list.append(word[::-1])\n\n# Operation 2:\njoined_text = ' '.join(word_list, '-')\n\n# Operation 3:\nreplaced_text = text.replace(\"mysteries\", \"secrets\")" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "This snippet is categorized under 'String Operations and Methods' and explicitly discusses the .replace() method, which helps a student verify that Operation 3 in the question is likely correct." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "This snippet is categorized under 'String Operations and Methods' and explicitly discusses the .replace() method, which helps a student verify that Operation 3 in the question is likely correct." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows string slicing syntax ([1::2]) and mentions reversing, which provides context for the reversing slice [::-1] used in Operation 1." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Validates that .append() is a standard method for adding items to a list, which supports the logic in Operation 1." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "This snippet is categorized under 'String Operations and Methods' and explicitly discusses the .replace() method, which helps a student verify that Operation 3 in the question is likely correct.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Shows string slicing syntax ([1::2]) and mentions reversing, which provides context for the reversing slice [::-1] used in Operation 1.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Validates that .append() is a standard method for adding items to a list, which supports the logic in Operation 1.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-4-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-4-w2-conditions" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets help rule out Operation 1 (slicing/append) and Operation 3 (replace), but none of the provided candidates describe the syntax or argument requirements for the .join() method. The error in Operation 2 is specifically about passing two arguments to .join() instead of one iterable; without a snippet defining .join()'s signature, a student cannot definitively identify this error.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing documentation or examples for the string .join() and .split() methods, specifically their parameter signatures.", + "missing_concepts": [ + "str.join() argument signature", + "str.split() behavior" + ], + "proposed_fix": "Add a reference snippet for common string methods that explicitly shows '.join(iterable)' taking exactly one argument." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet titled 'String Methods: Join and Split' with content: 'The .join() method is called on a separator string and takes exactly one argument (a list or iterable of strings), e.g., \"-\".join([\"a\", \"b\"]). Passing multiple arguments to .join() will result in a TypeError.'", + "why_helpful": "Directly addresses the misconception tested in Operation 2.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:47:25Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-4-w2-conditions", + "snippet_label": "String Operations and Methods", + "week": 4, + "topic": "String Operations and Methods", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes?\nA\nB\nC\nD\nA\nStrings in Python are immutable. The .replace() method returns a new string but does not modify the original. Option A returns the original string wit" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q18", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q18", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "6-strings - find - 2", + "question": "Suppose you have the following variables called sentence1 and sentence2 which contain strings. The sentences contain names, but they are not properly capitalized. You want to create a new string object called paragraph, with the proper nouns capitalized in the two sentences and the two sentences connected into one big string.\n\nThat is, if we execute the following line of code:\nprint(paragraph)\nthe output should be:\n\"Harry, Ron, and Hermione walked through the halls of Hogwarts; their footsteps echoing off the stone walls.\nThe Marauder's map in Harry's hands revealed the secret passageways and hidden rooms of the castle.\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor name in names:\n sentence1[sentence1.find(name)] = name.capitalize()\n sentence2[sentence2.find(name)] = name.capitalize()\nparagraph = sentence1 + \" \" + sentence2", + "b": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nfor word, name in zip(sentence1, names):\n if word == name:\n sentence1 = sentence1.replace(word, name.capitalize())\nfor word, name in zip(sentence2, names):\n if word == name:\n sentence2 = sentence2.replace(word, name.capitalize())\nparagraph = sentence1 + \" \" + sentence2", + "c": "names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']\nnew1 = ' '.join([word.capitalize() if word in names else word for word in sentence1])\nnew2 = ' '.join([word.capitalize() if word in names else word for word in sentence2])\nparagraph = new1 + \" \" + new2", + "d": "for word in ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']:\n sentence1 = sentence1.replace(word, word.capitalize())\n sentence2 = sentence2.replace(word, word.capitalize())\nparagraph = sentence1 + \" \" + sentence2" + }, + "correct": "d", + "explanation": "Option D correctly replaces each lowercase proper noun with its capitalized version in both strings and then concatenates the two sentences into paragraph.", + "code_context": "sentence1 = \"harry, ron, and hermione walked through the halls of hogwarts; their footsteps echoing off the stone walls.\"\nsentence2 = \"The marauder's map in harry's hands revealed the secret passageways and hidden rooms of the castle.\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions strings and the concept of upper/lower case versions of letters, although it does not provide the mechanics of the methods needed." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions strings and the concept of upper/lower case versions of letters, although it does not provide the mechanics of the methods needed." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions strings and character manipulation (dashes), providing some context that strings can be processed as objects." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions strings and the concept of upper/lower case versions of letters, although it does not provide the mechanics of the methods needed.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Mentions strings and character manipulation (dashes), providing some context that strings can be processed as objects.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the Python string methods '.replace()', '.capitalize()', or '.find()'. Furthermore, nothing explains string immutability (to reject option A) or how to concatenate strings with '+'. A student with zero knowledge would not be able to distinguish between the options based on these snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets are almost entirely focused on Dictionaries and OOP, whereas the question is purely about String manipulation methods and Immutability.", + "missing_concepts": [ + "string.replace()", + "string.capitalize()", + "string.find()", + "string immutability (cannot assign to index)", + "string concatenation with +" + ], + "proposed_fix": "Add a documentation-style snippet or an example snippet from Week 6 (Strings) that demonstrates these specific methods and mentions that strings cannot be modified in-place." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for '6-strings' showing: 1. s.replace(old, new) returns a NEW string. 2. s.capitalize() returns a capitalized version. 3. s.find(sub) returns the index. 4. Strings are immutable: s[0] = 'X' causes an error.", + "why_helpful": "This directly covers the mechanics tested in all four options (A, B, C, D).", + "why_maybe_unnecessary": "If the student has already reached Week 6 in the course, they might remember these, but for 'zero prior knowledge', it is essential.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:47:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q19", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q19", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - hard - 2", + "question": "Consider the following pandas DataFrame called df, and assume that Pandas is already imported.\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Name_Length that contains the length of each person's name\n- Operation 2: Replace all occurrences of the occupation 'Engineer' with 'Software Developer'\n- Operation 3: Extract the last two characters of each person's name and store them in a new column called Name_Suffix\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df['Name_Length'] = df['Name'].map(lambda x: len(x))\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:])", + "b": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']]\ndf['Name_Suffix'] = df['Name'].lambda x: x[-2:]", + "c": "df['Name_Length'] = len(df['Name'])\ndf['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[:-2])", + "d": "df['Name_Length'] = df['Name'].map(len)\ndf['Occupation'] = df['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x)\ndf['Name_Suffix'] = df['Name'].map(lambda x: x[-2:-1])" + }, + "correct": "a", + "explanation": "Option A correctly maps each name to its length, replaces only the Engineer entries, and slices the final two characters with x[-2:].", + "code_context": "Name Age Occupation\n0 John 25 Student\n1 Jane 30 Engineer\n2 Alex 35 Scientist\n3 Lisa 40 Doctor\n4 Mark 28 Architect" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions the .map() method being used to apply a function to a Series, which is fundamental to Operations 1 and 3 in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions the .map() method being used to apply a function to a Series, which is fundamental to Operations 1 and 3 in the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates how to create and assign a new column to a DataFrame (df['C'] = ...), which is used in all operations of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions the .map() method being used to apply a function to a Series, which is fundamental to Operations 1 and 3 in the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates how to create and assign a new column to a DataFrame (df['C'] = ...), which is used in all operations of the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover column assignment and the use of .map(). However, they do not explain string slicing syntax (like [-2:]) or list comprehensions with if/else logic, both of which are required to correctly identify option 'a' as the answer.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets lack coverage for Python's negative string slicing and conditional list comprehensions within a Pandas context.", + "missing_concepts": [ + "negative string slicing (e.g., [-2:] for suffixes)", + "list comprehensions with if-else logic", + "lambda functions in .map()" + ], + "proposed_fix": "Add a snippet or piece that demonstrates string slicing for character extraction and a conditional list comprehension used for data cleaning/replacement." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing string slicing examples: 'text'[-2:] gives 'xt'. Also show a list comprehension with a conditional: [val if condition else other_val for val in collection].", + "why_helpful": "This would allow a student to verify that x[-2:] correctly extracts the last two characters and that the syntax in Operation 2 of option 'a' is valid.", + "why_maybe_unnecessary": "String slicing might be considered a 'core' Python concept, but for a student with zero knowledge, the negative index is counter-intuitive.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:48:05Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q20", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q20", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - lambda - 2", + "question": "What will be printed by the following code?", + "options": { + "a": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 72 13\n1 B 45 19", + "b": "Product Units Price\n1 B 50 19\n0 A 100 10\n3 D 80 13\n2 C 200 15", + "c": "Product Units Price\n2 C 200 15\n0 A 100 10\n3 D 80 13\n1 B 50 19", + "d": "Product Units Price\n2 C 200 15\n3 D 80 13\n0 A 100 10\n1 B 50 19" + }, + "correct": "c", + "explanation": "UnitsCorrected and Revenue are used only for sorting; df1 keeps the original Units and Price columns, and sorting by descending revenue gives rows C, A, D, B.", + "code_context": "import pandas as pd\nd = {'Product':['A', 'B', 'C', 'D'], 'Units':[100, 50, 200, 80], 'Price':[10, 19, 15, 13]}\ndf = pd.DataFrame(d)\ndf.loc[:, 'UnitsCorrected'] = df.loc[:, 'Units'].map(lambda x: 0.9*x if x < 100 else x)\ndf.loc[:, 'Revenue'] = df.loc[:, 'UnitsCorrected'] * df.loc[:, 'Price']\ndf = df.sort_values(by='Revenue', ascending=False)\ndf1 = df.loc[:, ['Product', 'Units', 'Price']]\nprint(df1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly explains that the .map() method is used to apply a function to elements of a Series, which is essential for understanding the UnitsCorrected calculation." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly explains that the .map() method is used to apply a function to elements of a Series, which is essential for understanding the UnitsCorrected calculation." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates the creation of a new column (C) from existing columns (A and B), mirroring how 'Revenue' is created from 'UnitsCorrected' and 'Price'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "aiq-1", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Directly explains that the .map() method is used to apply a function to elements of a Series, which is essential for understanding the UnitsCorrected calculation.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates the creation of a new column (C) from existing columns (A and B), mirroring how 'Revenue' is created from 'UnitsCorrected' and 'Price'.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:aiq-1", + "rationale": "", + "needed_piece_ids": [ + "aiq-1" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While .map() and column creation are covered, there is a total absence of information regarding 'sort_values()', the 'ascending=False' parameter, or the 'value if condition else other' ternary syntax used in the lambda. A student would have to guess that 'ascending=False' means descending order to reach the correct answer 'c'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Crucial sorting operations and conditional logic within lambdas are not explained in the current snippets.", + "missing_concepts": [ + "sort_values()", + "ascending=False", + "conditional expressions (if-else ternary) in lambdas", + "selecting multiple columns via a list of names" + ], + "proposed_fix": "Add a snippet or key point covering DataFrame sorting (including direction) and the syntax for conditional logic within anonymous functions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point or example for 'Sorting and Selecting' that demonstrates 'df.sort_values(by=..., ascending=False)' and selecting a subset of columns using 'df[[...]]' or 'df.loc[:, [...]]'.", + "why_helpful": "Sorting is the final decisive step in this problem; without knowing if 'ascending=False' means high-to-low, the student cannot reliably choose between options like 'c' and 'd'.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add an example of a lambda with a conditional: 'lambda x: val1 if x < threshold else val2'.", + "why_helpful": "This specific syntax is used to calculate 'UnitsCorrected', which determines the sorting order.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:48:34Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:cs-b46633d18d", + "snippet_label": "Combining Data", + "week": 5, + "topic": "Combining Data", + "pieces": [ + { + "item_id": "cs-b46633d18d", + "item_type": "source_notebook", + "bucket": "recommended", + "topic": "Combining Data", + "subtopic_title": "", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noo" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping", + "week": 5, + "topic": "Combining Data", + "pieces": [ + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Combining Data", + "subtopic_title": "Concatenation, Merging, and Grouping", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noo" + }, + { + "item_id": "ai-example-5", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Combining Data", + "subtopic_title": "Concatenation, Merging, and Grouping", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\nprint(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noor" + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Combining Data", + "subtopic_title": "Concatenation, Merging, and Grouping", + "search_text": "Database-style joins using .merge(). 'how' determines the type (left, right, inner, outer)." + }, + { + "item_id": "kp-3", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Combining Data", + "subtopic_title": "Concatenation, Merging, and Grouping", + "search_text": "The Split-Apply-Combine pattern using .groupby()." + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Combining Data", + "subtopic_title": "Concatenation, Merging, and Grouping", + "search_text": "Left join on a key\ndf1.merge(df2, on='Town', how='left')\nDatabase-style joins using .merge(). 'how' determines the type (left, right, inner, outer)." + }, + { + "item_id": "ai-example-3", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Combining Data", + "subtopic_title": "Concatenation, Merging, and Grouping", + "search_text": "Grouped aggregation\ndf.groupby('Nationality')['Height'].median()\nThe Split-Apply-Combine pattern using .groupby()." + } + ] + }, + { + "snippet_id": "item:aiq-1", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Condition flow and branch result\nExam • midterm_2024 • Q1\nConsider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • trial_midterm • Q17\nA def square" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Combining Data", + "subtopic_title": "", + "search_text": "During a .merge(how='left') operation, what is placed in a cell if no match is found in the right DataFrame?\nPandas uses NaN (Not a Number) to represent missing data resulting from non-overlapping joins.\nMerging" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "What happens if you run print(df.iloc[5, 2]) on a DataFrame with only 3 rows?\nUnlike slicing, accessing a specific single position with .iloc that is out of bounds raises an IndexError.\nSelection with iloc" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types.\nI is correct (e.g. a=1, b=2, both int). II is incorrect — if two objects have the same value " + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Operators and Truth", + "subtopic_title": "", + "search_text": "What is the result of (a//b)*b + a%b?\nArithmetic operators" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q21", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q21", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_2", + "question": "You have the following definition for a class called Calendar.\n\nThe method check_overlap() should return True if there are two overlapping events and False if the two events are not overlapping.\n\nFor example, if we have the following Calendar objects:\nevent1 = Calendar('Coffee meeting', '01-06-2023 9:30', 20)\nevent2 = Calendar('Writing session', '01-06-2023 10:00', 150)\nevent3 = Calendar('Lunch meeting', '01-06-2023 12:00', 45)\n\nthe following command should return False:\nprint(event1.check_overlap(event2))\n\nand the following command returns True:\nprint(event2.check_overlap(event3))\n\nDoes the code segment given above do what you want? If not, then why not?\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the condition provided after the return keyword is incorrect.", + "c": "This code segment does not work because the syntax to parse the input string to create a datetime object is incorrect.", + "d": "This code segment does not work because the __init__ method needs 4 parameters and only 3 arguments are passed." + }, + "correct": "a", + "explanation": "The datetime format string matches the input values, timedelta(minutes=length) creates the correct end time, and the overlap condition correctly detects whether two intervals intersect.", + "code_context": "from datetime import datetime, timedelta\n\nclass Calendar():\n def __init__(self, event, start, length):\n self.event = event\n self.start = datetime.strptime(start, '%d-%m-%Y %H:%M')\n self.end = self.start + timedelta(minutes=length)\n def check_overlap(self, other):\n return self.start < other.end and self.end > other.start" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to define a method ('compare') that compares 'self' to 'other', which is the core structure of the 'check_overlap' method in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to define a method ('compare') that compares 'self' to 'other', which is the core structure of the 'check_overlap' method in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides context for class initialization and attribute assignment in the __init__ method, helping to evaluate option (d)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Shows how to define a method ('compare') that compares 'self' to 'other', which is the core structure of the 'check_overlap' method in the question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides context for class initialization and attribute assignment in the __init__ method, helping to evaluate option (d).", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the hint explains 'timedelta' conceptually, no snippet covers the 'datetime.strptime' syntax or the specific logic required for interval overlap (comparison of start/end times across objects). A student would not know if the date format string is correct or if the overlap condition is logically sound.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus on basic OOP and data structures, completely missing the 'datetime' module and interval comparison logic.", + "missing_concepts": [ + "datetime.strptime format codes", + "datetime arithmetic with timedelta", + "Interval overlap logic (A.start < B.end and A.end > B.start)" + ], + "proposed_fix": "Add a snippet family for 'Date and Time' that includes strptime examples and basic datetime comparisons." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Basics' snippet showing 'datetime.strptime(string, format)' with common codes like %d, %m, %Y, %H, %M and an example of adding a 'timedelta' to a datetime object.", + "why_helpful": "This would allow the student to verify option (c) and the calculation of 'self.end' in the code context.", + "why_maybe_unnecessary": "The question includes a text hint for timedelta, but it lacks the syntax/usage code.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:48:56Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q22", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q22", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_1", + "question": "You want to create a DataFrame called df that has the following format:\n\n Day Month Year\n01-01-23 1 1 2023\n08-01-23 8 1 2023\n15-01-23 15 1 2023\n22-01-23 22 1 2023\n29-01-23 29 1 2023\n\nWhich of the following code segments achieves what you want?\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module, as well as the pandas module (via: import pandas as pd).\n\nHint:\nThe timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration.", + "options": { + "a": "dates = [(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=[date.strftime('%d-%m-%y') for date in dates])", + "b": "dates = [(datetime(2023, 1, 1) + timedelta(days=7*i)).strftime('%d-%m-%y') for i in range(5)]\ndata = {'Day': [date.day for date in dates],\n 'Month': [date.month for date in dates],\n 'Year': [date.year for date in dates]}\ndf = pd.DataFrame(data, index=dates)", + "c": "day = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).day for i in range(5)])\nmonth = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).month for i in range(5)])\nyear = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).year for i in range(5)])\ndf = pd.DataFrame(data=[day, month, year])", + "d": "df = pd.DataFrame(index=[(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)],\n {'Day': [date.days for date in index],\n 'Month': [date.months for date in index],\n 'Year': [date.year for date in index]})" + }, + "correct": "a", + "explanation": "Option A keeps real datetime objects long enough to derive day, month, year, and then formats those dates into the desired string index for the DataFrame.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary structure which is the basis for the 'data' variable used to construct the DataFrame in the options." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary structure which is the basis for the 'data' variable used to construct the DataFrame in the options." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Displays what a printed DataFrame looks like, helping the student visualize the goal (index and columns)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary structure which is the basis for the 'data' variable used to construct the DataFrame in the options.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Displays what a printed DataFrame looks like, helping the student visualize the goal (index and columns).", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The provided snippets completely lack coverage of the 'datetime' module, 'timedelta' class, 'strftime' method, and the specific syntax for initializing a Pandas DataFrame with a manual index.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary difficulty is the logic involving datetime object manipulation and formatting.", + "missing_concepts": [ + "datetime module attributes (.day, .month, .year)", + "timedelta parameter usage (weeks vs days)", + "strftime() string formatting syntax", + "pd.DataFrame(data, index=...) parameter usage" + ], + "proposed_fix": "Add a snippet or key point piece explaining how to generate date ranges using timedelta and how to convert datetime objects to formatted strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet covering Datetime Fundamentals: 'datetime(y, m, d)' for creation, 'timedelta(weeks=n, days=n)' for arithmetic, and 'date.strftime('%d-%m-%y')' for formatting. Include a small example of creating a DataFrame from a dict with an index list.", + "why_helpful": "This would directly allow a student to evaluate why 'timedelta(weeks=1*i)' and 'strftime' are used in the correct option.", + "why_maybe_unnecessary": "If the exam focuses on logic rather than library specificities, but this question is highly specific to those libraries.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:49:16Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q23", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q23", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Function_3", + "question": "You have the following definition of a class called Pack.\n\nYou want to add to this class a method called fitting() that calculates how many times another object of the class Pack would fit inside this object.\nThe method should return the number of times these other objects would fit completely in this object, and the final value.\nThe final value is the sum of all values of all objects that fit in it, plus the value of the carrying object self.\n\nFor example, if we execute the lines of code:\nbackpack = Pack(size=15, value=20)\nbook = Pack(size=4, value=10)\nbackpack.fitting(book)\n\nthe output should be:\nAmount: 3. Value: 50.\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def fitting(self, other):\n if self.size > other.size:\n self.total = (self.size // other.size) * other.value + self.value\n return f'Amount: {self.size // other.size}. Value: {self.total}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "b": "def fitting(self, other):\n if self.size > other.size:\n return f'Amount: {self.size // other.size}. Value: {other.value * other.size}.'\n else:\n return f'Amount: 0. Value: {self.value}.'", + "c": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return f'Amount: {self.amount}. Value: {self.total}.'", + "d": "def fitting(self, other):\n self.amount = self.size / other.size\n self.total = self.amount * other.value\n return 'Amount: {}. Value: {}.'.format(self.amount, self.value if self.size > other.size else self.total)" + }, + "correct": "a", + "explanation": "Option A uses integer floor division to count only full fits, adds the carried items' value plus self.value, and returns zero items with self.value when the other object does not fit.", + "code_context": "class Pack:\n def __init__(self, size, value = 0):\n self.size = size\n self.value = value\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This piece describes a method ('compare') that compares one object ('self') to another object of the same class, which is the exact architectural pattern required for the 'fitting' method." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This piece describes a method ('compare') that compares one object ('self') to another object of the same class, which is the exact architectural pattern required for the 'fitting' method." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows string formatting patterns for injecting variables into descriptive text, helping the student understand the return statements in the options." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining classes and attributes, making it clear what 'self.size' and 'self.value' represent." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This piece describes a method ('compare') that compares one object ('self') to another object of the same class, which is the exact architectural pattern required for the 'fitting' method.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows string formatting patterns for injecting variables into descriptive text, helping the student understand the return statements in the options.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining classes and attributes, making it clear what 'self.size' and 'self.value' represent.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class method structure and string formatting, but they do not explain the difference between floor division (//) and float division (/), which is the primary technical distinciton between the correct answer and the distractors.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The student can infer the class structure and string output, but lacks the specific knowledge that // is required for 'fitting completely' (integer division).", + "missing_concepts": [ + "floor division operator (//) vs float division (/)" + ], + "proposed_fix": "Add a snippet explaining basic Python arithmetic operators, specifically contrasting / and //." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Python Arithmetic: / (Standard Division) vs // (Floor/Integer Division). Example: 15 / 4 = 3.75, whereas 15 // 4 = 3 (number of times it fits completely).", + "why_helpful": "Explicitly clarifies the 'Amount' calculation which is the main logic gate for this question.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:49:36Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q24", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q24", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Hard_1", + "question": "You have the following definition for a class called Piece.\n\nAnd the creation of three objects with the help of the class definition:\na = Piece(diagonal=True, straight=False, initial_position=(0, 0))\nb = Piece(diagonal=False, straight=True, initial_position=(4, 3))\nc = Piece(diagonal=True, straight=True, initial_position=(9, 6))\n\nIf we run the following statements:\nprint(a.check_move((4, 4)))\nprint(b.check_move((5, 5)))\nprint(c.check_move((6, 6)))\n\nThis will print 3 Boolean values. Of these values, how many times will this be True?", + "options": { + "a": "0", + "b": "1", + "c": "2", + "d": "3" + }, + "correct": "b", + "explanation": "The first move fails because the row and column differences are both 4, which is above the allowed maximum of 3. The second fails because a straight-only piece cannot move diagonally. The third succeeds because a piece that can move straight and diagonally may move along the same column within 3 steps, so exactly one result is True.", + "code_context": "class Piece:\n def __init__(self, diagonal, straight, initial_position):\n self.diagonal = diagonal\n self.straight = straight\n self.initial_position = initial_position\n\n def check_move(self, target_position):\n self.target_position = target_position\n self.row_diff = self.target_position[0] - self.initial_position[0]\n if abs(self.row_diff) > 3:\n return False\n self.col_diff = self.target_position[1] - self.initial_position[1]\n if abs(self.col_diff) > 3:\n return False\n\n if self.diagonal and (not self.straight):\n return abs(self.row_diff) == abs(self.col_diff)\n if self.straight and (not self.diagonal):\n return abs(self.row_diff) == 0 or abs(self.col_diff) == 0\n if self.straight and self.diagonal:\n return (abs(self.row_diff) == abs(self.col_diff)) or (abs(self.row_diff) == 0 or abs(self.col_diff) == 0)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet explains the fundamental structure of a class, the constructor method (__init__), and how attributes are initialized and stored, which is the first step in understanding the Piece class definition and how the instances (a, b, c) are created." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet explains the fundamental structure of a class, the constructor method (__init__), and how attributes are initialized and stored, which is the first step in understanding the Piece class definition and how the instances (a, b, c) are created." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Provides an example of a class method (compare), helping the student understand that objects can have functions (methods) that perform logic using their internal attributes (like check_move does here)." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions return values like True or False, and the 'Working With Values' section provides context on Booleans." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet explains the fundamental structure of a class, the constructor method (__init__), and how attributes are initialized and stored, which is the first step in understanding the Piece class definition and how the instances (a, b, c) are created.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Provides an example of a class method (compare), helping the student understand that objects can have functions (methods) that perform logic using their internal attributes (like check_move does here).", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions return values like True or False, and the 'Working With Values' section provides context on Booleans.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover the general structure of classes, constructors, and return statements. However, the question requires a zero-knowledge student to correctly interpret tuple indexing (e.g., target_position[0]) and the mathematical function abs(). Neither of these are explained in the current candidates, making the coordinate math difficult to trace accurately.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing core syntax for coordinate tracing (indexing and absolute values).", + "missing_concepts": [ + "Tuple indexing (using [0] and [1] to access coordinates)", + "The abs() function for calculating absolute differences", + "Tracing multiple Boolean conditions (and, or, not) in a single statement" + ], + "proposed_fix": "Add a foundational snippet explaining how 'tuple' data (like coordinates) is accessed via indices and demonstrating the use of abs() for calculating distances or differences between points." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Working with Coordinates and Math' snippet that demonstrates: 1. Accessing tuple elements (e.g., x = pos[0]); 2. Calculating differences between points; 3. Using abs() to ensure positive results.", + "why_helpful": "The entire question hinges on correctly calculating row_diff and col_diff from (x, y) coordinates. A student who doesn't know what [0] means in this context will be unable to trace the code.", + "why_maybe_unnecessary": "Indices are somewhat intuitive, but for a true 'zero prior knowledge' baseline, explicit confirmation that [0] is the first item and [1] is the second is necessary.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:50:16Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 357615", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "All three expressions evaluate to True: 2 * 3 = 6 equals x[2][1], 3 + 5 = 8 equals x[-1][1], and 7 - 5 = 2 equals x[0][1].", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the only remaining snippet that mentions lists and indexing (slicing), although it is insufficient for explaining nested indexing or negative indexing." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the only remaining snippet that mentions lists and indexing (slicing), although it is insufficient for explaining nested indexing or negative indexing." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Mentions lists and basic operations, providing minimal additional context for list-related terminology." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Provides the most relevant general context for lists among non-identical items." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "This piece contains the exact same code context, question, and evaluates the options (A, B, and C) identically to the provided question JSON." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Matches the question context perfectly and explicitly explains why all lines evaluate to True." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the only remaining snippet that mentions lists and indexing (slicing), although it is insufficient for explaining nested indexing or negative indexing.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Mentions lists and basic operations, providing minimal additional context for list-related terminology.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Provides the most relevant general context for lists among non-identical items.", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "Beyond the near-identical past exam questions, there is no informational snippet explaining Python's zero-based indexing, negative indexing, or nested sequence access (e.g., list[i][j]). A student with zero knowledge would be unable to solve this logically with the provided non-identical snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate list lacks foundational documentation for sequence indexing rules.", + "missing_concepts": [ + "Zero-based indexing", + "Negative indexing (e.g., -1 is the last element)", + "Nested indexing for lists containing tuples", + "Basic arithmetic/equality logic with indexed variables" + ], + "proposed_fix": "Add a foundational 'List and Tuple Indexing' topic card covering both positive/negative indices and nested access." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Python Indexing Rules' snippet. Include: 1. `data[0]` is first, `data[n-1]` is last. 2. `data[-1]` is last, `data[-2]` second-to-last. 3. `data[i][j]` accesses inner elements. Provide a clear example matching the list-of-tuples structure.", + "why_helpful": "It allows a student to derive the answer for any indexing question rather than relying on memorizing specific past exam results.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:50:59Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q02", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q02", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 357607", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "The function called power should not return the string 'The result of {} ** {} is: {}'.format(num, factor, result), but the value of result.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "Result is a local name that cannot be referenced outside of the function power." + }, + "correct": "d", + "explanation": "`result` is defined inside the function `power`, so it is local to that function. The statement `print(result)` outside the function therefore raises a name error because `result` is not defined there.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}'.format(num, factor, result)\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Directly defines 'local names' as those assigned inside a function and explicitly states they are only known inside that function." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Directly defines 'local names' as those assigned inside a function and explicitly states they are only known inside that function." + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "Reinforces that 'local names are gone after function ends' and that a function 'leaves no traces' outside itself." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a slightly more complex application of the same scope rule (nested scope), which helps verify the student understands the general principle." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "rationale": "Identical question code context (power function) and explanation." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Identical question code context (power function) and explanation." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Identical logic and variable name ('result'); only the function name is changed to 'cube'." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "Directly defines 'local names' as those assigned inside a function and explicitly states they are only known inside that function.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-00b2983ca8", + "rationale": "Reinforces that 'local names are gone after function ends' and that a function 'leaves no traces' outside itself.", + "critical_piece_ids": [ + "ks-00b2983ca8" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a slightly more complex application of the same scope rule (nested scope), which helps verify the student understands the general principle.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-2-w3-scope" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:ks-00b2983ca8", + "rationale": "", + "needed_piece_ids": [ + "ks-00b2983ca8" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The concept of local scope is explicitly defined in the lecture snippets, explaining that 'result' (assigned inside 'power') is unknown outside.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The provided lecture snippets provide sufficient conceptual coverage to answer the question without relying on the near-identical exam items.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:51:21Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:ks-00b2983ca8", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "ks-00b2983ca8", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Return statement\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.\nReturning a tuple (multiple values)\ndef po" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice - Question-ID: 355235", + "question": "What will be printed by the following code segment?", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[]", + "d": "[None]" + }, + "correct": "d", + "explanation": "The code appends list-typed elements to `y`, but the return expression uses `append`, which itself returns `None`. The page marks option D as correct, so the intended evaluated output is `[None]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n\n return [y.append(i)]\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Explicitly demonstrates the .append() method on a list, which is the central operation in the question's return statement." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Explicitly demonstrates the .append() method on a list, which is the central operation in the question's return statement." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Helps a student understand the basic structure of a function that iterates through a list and conditionally appends to a new list, providing context for the first half of the code context." + }, + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Introduces the concept of 'None' being a specific return value/placeholder in Python functions." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Uses the exact same loop logic (iterating through a list and checking if type(i) == type(x)) and input elements, although it focuses on a variant where the function returns the modified list 'y' rather than the result of the append call." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Identical logic setup involving type checking and list filtering, but different return behavior statement." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Explicitly demonstrates the .append() method on a list, which is the central operation in the question's return statement.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Helps a student understand the basic structure of a function that iterates through a list and conditionally appends to a new list, providing context for the first half of the code context.", + "critical_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Introduces the concept of 'None' being a specific return value/placeholder in Python functions.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The core trick of the question is that the 'append()' method returns 'None'. None of the snippets mention that list methods perform in-place modification and return None. A student using the snippets would likely understand the loop logic (filtering for lists) and incorrectly conclude the answer is [[]] (Option B) because they assume append returns the list it was called on.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing a conceptual explanation that in-place list methods like append() return None.", + "missing_concepts": [ + "The return value of the list.append() method is None." + ], + "proposed_fix": "Add a snippet or detail rule explaining that methods that modify objects in-place (like append, sort, extend) return None." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet: 'Methods that change a list (like .append(), .extend(), .sort(), or .remove()) do their work and then return None. This means if you write x = mylist.append(item), x will be None.'", + "why_helpful": "This is a recurring 'gotcha' in Intro to Python exams that tests whether students understand the difference between in-place modification and returning a new value.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:53:20Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "function defaults and loops", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "This code produces an error as there is a missing argument when calling main.", + "b": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10']", + "c": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')", + "d": "['1 * 1 = 1',\n '1 * 2 = 2',\n '1 * 3 = 3',\n '1 * 4 = 4',\n '1 * 5 = 5',\n '1 * 6 = 6',\n '1 * 7 = 7',\n '1 * 8 = 8',\n '1 * 9 = 9',\n '1 * 10 = 10',\n '1 * 11 = 11']" + }, + "correct": "b", + "explanation": "`main(1)` is valid because `y` has default value `11`. The loop starts at `i = 1` and runs while `i < y`, so it appends the multiplication strings for 1 through 10 and stops before 11.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nprint(main(1))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "The clearest demonstration of default arguments in function definitions, which is the primary concept needed to understand why main(1) works." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "The clearest demonstration of default arguments in function definitions, which is the primary concept needed to understand why main(1) works." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a function using a default argument and demonstrates building a list using the .append() method within a loop." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Explains how arguments default to a value when omitted in the function call." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Covers the mechanics of list construction via the append method." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "Directly matches the question's function, call, and logic explanation regarding the default argument and loop range." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "Identical question template covering the same function logic and default argument behavior." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "The clearest demonstration of default arguments in function definitions, which is the primary concept needed to understand why main(1) works.", + "critical_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a function using a default argument and demonstrates building a list using the .append() method within a loop.", + "critical_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "Explains how arguments default to a value when omitted in the function call.", + "needed_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Covers the mechanics of list construction via the append method.", + "needed_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "high", + "rationale": "The core hurdle (default arguments) is well-covered. While f-strings and while-loop boundaries aren't explicitly explained as concepts, their behavior can be inferred from the provided logic and the identical past exam questions.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing conceptual coverage for 'while loop' stop boundaries and 'f-string' interpolation.", + "missing_concepts": [ + "while loop stop condition", + "f-strings" + ], + "proposed_fix": "Add a conceptual snippet explaining that 'while i < 11' runs for values 1-10 but stops at 11, and a basic f-string syntax example." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a conceptual snippet for f-strings showing: x = 5; print(f'Value is {x}') -> Value is 5.", + "why_helpful": "Helps students understand how variables are injected into strings in the multiplication table.", + "why_maybe_unnecessary": "The provided options clearly show the resulting string format, making the syntax somewhat self-explanatory.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:53:56Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. C" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-12-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-12-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA [10, 20, 30, 40, 1, 2, 3, 4]\nB [11, 22, 33, 44]\nC This code will result in an error because you cannot " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "list slicing and sets", + "question": "Suppose you have a list called x, where:\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Option A removes duplicates and sorts descending, which gives `[5, 4, 3, 2, 1]`. Option B takes every second element from the end of the symmetric list and also prints `[5, 4, 3, 2, 1]`.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n# target output:\n# [5, 4, 3, 2, 1]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only non-identical snippet that demonstrates list slicing syntax (e.g., [1::2]), which is relevant to Option B, although it does not cover negative steps." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only non-identical snippet that demonstrates list slicing syntax (e.g., [1::2]), which is relevant to Option B, although it does not cover negative steps." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides a baseline for understanding list indexing and slicing syntax." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This piece is an exact match for the question, containing the same list 'x', target output, and a detailed explanation of why Options A and B both work." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Virtually identical to the current question, providing the same code logic and a very clear explanation of the set() and sorting mechanics." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "This is the only non-identical snippet that demonstrates list slicing syntax (e.g., [1::2]), which is relevant to Option B, although it does not cover negative steps.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Provides a baseline for understanding list indexing and slicing syntax.", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Without the near-identical past exam questions, the candidate snippets are insufficient. There is no general reference explaining that set() removes duplicates, how sorted() works with the reverse parameter, or how negative steps in slicing (like [::-2]) reverse the traversal order.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The knowledge base lacks general reference material for sets, sorting parameters, and advanced slicing behavior.", + "missing_concepts": [ + "set() function for removing duplicates", + "sorted() function with the reverse=True parameter", + "Slicing with negative steps (backwards traversal)" + ], + "proposed_fix": "Add a foundational reference snippet covering list/set conversions and advanced slicing mechanics." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Python Sequences: Slicing, Sets, and Sorting\nContent:\n1. Advanced Slicing: list[start:stop:step]. A negative step (e.g., [::-1]) reverses the list. [::-2] reverses and skips every second element.\n2. Unique Elements: set(list) removes all duplicate items.\n3. Descending Sort: sorted(list, reverse=True) sorts items in descending order (e.g., [5, 4, 3, 2, 1]).", + "why_helpful": "Directly explains the underlying Python mechanics for both Option A and Option B, making the question answerable through logic rather than pattern matching against past exams.", + "why_maybe_unnecessary": "The student might already be expected to know these basic built-ins, but for 'zero prior knowledge' students, this is critical.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:54:27Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "keyword arguments", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "To sum the numeric keyword-argument values, the function must iterate over `kwargs.values()`. Option A adds the string keys instead of the prices, and Option C incorrectly tries to unpack `kwargs.keys()`.", + "code_context": "main(apple=1.99, banana=0.99, orange=1.49)\n# should return 4.47" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Directly demonstrates the `**kwargs` syntax for capturing a 'flexible number of keyword arguments', which is the first step in identifying the correct function signature." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Directly demonstrates the `**kwargs` syntax for capturing a 'flexible number of keyword arguments', which is the first step in identifying the correct function signature." + }, + { + "item_id": "aiq-4", + "rationale": "The first piece reinforces `**kwargs` usage for keyword arguments and mentions dictionaries, which helps a student infer that `kwargs` can be manipulated like a dictionary." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Exact match for the question regarding a main function summing keyword arguments." + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Identical question structure, function name, and example values." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "rationale": "Directly demonstrates the `**kwargs` syntax for capturing a 'flexible number of keyword arguments', which is the first step in identifying the correct function signature.", + "critical_piece_ids": [ + "exam-midterm_2023-10-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "The first piece reinforces `**kwargs` usage for keyword arguments and mentions dictionaries, which helps a student infer that `kwargs` can be manipulated like a dictionary.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-10-w3-arguments" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets confirm that `**kwargs` is the correct syntax for 'flexible keyword arguments'. However, they do not explicitly explain dictionary methods like `.values()`, `.items()`, or `.keys()`, which are required to distinguish between options A, B, and C without prior Python knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing an explanation of how to iterate over the values of a `**kwargs` dictionary vs its keys or items.", + "missing_concepts": [ + "kwargs.values()", + "kwargs.items()", + "kwargs.keys()", + "Dictionary iteration methods" + ], + "proposed_fix": "Add a snippet explaining that `**kwargs` creates a dictionary and showing how to use `.values()` to access the numeric values passed as arguments." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'Iterating over Keyword Arguments (**kwargs): The **kwargs syntax collects arguments into a dictionary. Use kwargs.values() to get the values (e.g., prices), kwargs.keys() for the names (e.g., apple), and kwargs.items() for both pairs.'", + "why_helpful": "Provides the missing link needed to distinguish between the summation logic in options A and B.", + "why_maybe_unnecessary": "A student might guess that 'values' is the intuitive method for summing 'values of the arguments'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:55:00Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 29, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments." + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Which update makes `library['books'] = 6` and adds `library['years']`?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q8" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q07", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {word: len for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to the length of that word. The other options either reverse key/value order or use invalid logic.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This is the best non-identical example as it describes the exact task required: creating a dictionary from a list where elements (names) are mapped to values (ages), which is conceptually identical to mapping words to lengths." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This is the best non-identical example as it describes the exact task required: creating a dictionary from a list where elements (names) are mapped to values (ages), which is conceptually identical to mapping words to lengths." + }, + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Provides code for a manual dictionary-building loop ('counts[letter] = 1'), which helps a student understand the underlying key-value assignment logic that dictionary comprehensions simplify." + }, + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Another relevant example of mapping list data (students/grades) into a dictionary structure (grade_counts)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This is the exact same question, using the same variables (words, word_lengths) and testing the same logic (mapping strings to their lengths)." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This is the best non-identical example as it describes the exact task required: creating a dictionary from a list where elements (names) are mapped to values (ages), which is conceptually identical to mapping words to lengths.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "Provides code for a manual dictionary-building loop ('counts[letter] = 1'), which helps a student understand the underlying key-value assignment logic that dictionary comprehensions simplify.", + "critical_piece_ids": [ + "exam-trial_midterm-19-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Another relevant example of mapping list data (students/grades) into a dictionary structure (grade_counts).", + "critical_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the past exam database. However, without the identical snippet, answerability would be 'insufficient' because no other snippet explicitly demonstrates or explains the dictionary comprehension syntax {key: value for item in iterable}.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The database lacks a general reference for dictionary comprehension syntax. Students can only solve this by finding the identical past question or inferring from manual dictionary assignment snippets.", + "missing_concepts": [ + "Dictionary comprehension syntax", + "{k: v for ...} pattern vs list comprehensions" + ], + "proposed_fix": "Add a foundational 'Key Point' snippet explaining Dictionary Comprehensions with the syntax rule and a simple example." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Dictionary Comprehensions. Content: You can create dictionaries using comprehensions. Syntax: {key_expression: value_expression for item in iterable}. Example: if words = ['apple', 'pear'], then {w: len(w) for w in words} results in {'apple': 5, 'pear': 4}.", + "why_helpful": "Explicitly explains the syntax being tested, allowing students to understand WHY 'c' is correct rather than just recognizing the question.", + "why_maybe_unnecessary": "The information is implicitly covered by the identical past exam question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:55:56Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]," + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q08", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades.\n\nThe students list contains strings representing the names of students.\nThe grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears. B builds lists of students per grade instead of counting them.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet provides the closest structural template for building a dictionary from a list via a loop and confirms that the 'Option A' pattern is the standard valid solution for this type of task." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet provides the closest structural template for building a dictionary from a list via a loop and confirms that the 'Option A' pattern is the standard valid solution for this type of task." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the use of two lists (names, ages) to create a dictionary, which mirrors the students/grades setup in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This is an exact duplicate of the current question, using the same variables (students, grades), data values, and expected dictionary output." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet provides the closest structural template for building a dictionary from a list via a loop and confirms that the 'Option A' pattern is the standard valid solution for this type of task.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the use of two lists (names, ages) to create a dictionary, which mirrors the students/grades setup in the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The library contains an identical match in the 'extra_practice' set. Without this specific match, answerability would be 'insufficient' because none of the non-identical snippets explicitly demonstrate the 'if key not in dict: dict[key] = 0' counting logic.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The library relies on the student finding an identical past-exam question rather than teaching the underlying 'Frequency Counting' pattern.", + "missing_concepts": [ + "Dictionary frequency counting / accumulator pattern", + "Initializing dictionary keys with 'if key not in dict'", + "Differentiating between counting (integers) and grouping (lists)" + ], + "proposed_fix": "Add a core concept snippet for 'Dictionary Patterns: Counting' that explains the initialization and increment logic generically." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet under the 'Dictionaries and Mappings' topic titled 'Pattern: Counting Occurrences'. It should show a simple loop: for item in list: if item not in counts: counts[item] = 0; counts[item] += 1.", + "why_helpful": "This is a fundamental pattern tested in multiple exams but not currently explicitly explained in a general-purpose snippet.", + "why_maybe_unnecessary": "Students can find the answer by searching for the identical exam question, but they won't understand the logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:56:55Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q09", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the right result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Provides a very similar scenario (employee_ratings dictionary) where the student must find and print specific names based on value comparisons, demonstrating dictionary iteration and value access." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Provides a very similar scenario (employee_ratings dictionary) where the student must find and print specific names based on value comparisons, demonstrating dictionary iteration and value access." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Focuses on calculating an average from dictionary values (monthly_sales), which is the first step in both provided code segments." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Validates the logic of iterating through keys and accessing values in a dictionary context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Directly matches the question text, variable names (math_scores), and logic (scores above average)." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "Provides a very similar scenario (employee_ratings dictionary) where the student must find and print specific names based on value comparisons, demonstrating dictionary iteration and value access.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Focuses on calculating an average from dictionary values (monthly_sales), which is the first step in both provided code segments.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Validates the logic of iterating through keys and accessing values in a dictionary context.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The near-identical piece confirms the answer, while the combination of other exam-style snippets provides the necessary logic for average calculation and dictionary filtering to solve it from first principles.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the exam patterns are present, the extreme truncation of the snippets ('Which', 'Option A is...') makes them harder to read than a dedicated explanation of dictionary methods would be.", + "missing_concepts": [ + "Explicit explanation that sum(d.values()) / len(d) is a standard idiom for average.", + "Difference between iterating over 'd' vs 'd.keys()'." + ], + "proposed_fix": "Add a conceptual snippet explaining 'Dictionary Math and Filtering' to move beyond pattern-matching past exams." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a tutorial item: 'Dictionary Aggregates and Filtering'. Code example: scores = {'a':10, 'b':20}; avg = sum(scores.values())/len(scores); for k in scores: if scores[k] > avg: print(k). Explain that sum() works on values and len() on the whole dict.", + "why_helpful": "Provides the student with the 'why' and 'how' behind the logic, rather than just a similar exam question to mimic.", + "why_maybe_unnecessary": "The existing 'near-identical' piece makes the question trivial for a student to answer correctly by matching.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:57:25Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-1", + "rationale": "This family contains a piece on String Fundamentals (capitalize()) and Higher-Order Patterns (iterating transformations), which are the closest conceptual matches to string methods and list comprehensions." + }, + "top_three_snippets": [ + { + "item_id": "aiq-1", + "rationale": "This family contains a piece on String Fundamentals (capitalize()) and Higher-Order Patterns (iterating transformations), which are the closest conceptual matches to string methods and list comprehensions." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows that a string can be converted to a list of characters using list() and slicing, which helps understand the structure of the expected output." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Explicitly mentions 'lowercase vowels', providing a hint that 'lowercase' is a relevant category for character classification in the course." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-1", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-1", + "rationale": "This family contains a piece on String Fundamentals (capitalize()) and Higher-Order Patterns (iterating transformations), which are the closest conceptual matches to string methods and list comprehensions.", + "critical_piece_ids": [ + "aiq-1" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Shows that a string can be converted to a list of characters using list() and slicing, which helps understand the structure of the expected output.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Explicitly mentions 'lowercase vowels', providing a hint that 'lowercase' is a relevant category for character classification in the course.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-1", + "rationale": "", + "needed_piece_ids": [ + "aiq-1" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "No snippet explains the 'islower()' method or the specific syntax of list comprehensions (the '[x for x in y if condition]' pattern). A student without prior knowledge would not know if 'islower()' returns true for spaces or punctuation, nor how the filter logic works.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing explanations for list comprehension syntax and the .islower() string method.", + "missing_concepts": [ + "List comprehensions with 'if' filters", + "String predicate methods (.islower, .isupper, .isdigit, .isalpha)" + ], + "proposed_fix": "Add a snippet explaining list comprehensions as a shorthand for 'create list, loop, if condition, append' and a reference for common string methods like .islower()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: List Comprehensions. Content: [expression for item in iterable if condition] is a shorthand to create a new list. It iterates through the 'iterable', checks the 'if condition', and if True, adds the 'expression' to the result list. Example: [c for c in 'Abc' if c.islower()] -> ['b', 'c'].", + "why_helpful": "This directly explains the syntax used in the question, allowing the student to decode the logic.", + "why_maybe_unnecessary": "Basic list comprehensions might be covered in general loop materials, but the 'if' filter is a specific hurdle.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Predicate Methods. Content: Methods starting with 'is...' check characters. .islower() returns True ONLY if the character is a lowercase letter. It returns False for uppercase letters, spaces, numbers, and punctuation.", + "why_helpful": "The student must know if spaces and punctuation are included in the result; this clarifies that only lowercase letters pass.", + "why_maybe_unnecessary": "Common sense might lead some to guess correctly, but 'islower' is a specific technical term.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:57:47Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:aiq-1", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Fundamentals", + "subtopic_title": "", + "search_text": "Given s1 = 'abcd', which code fragment correctly updates s1 to 'Abcd'?\nStrings are immutable. s1.capitalize() returns a new string, so you must assign that result back to the name s1.\nString Methods" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Condition flow and branch result\nExam • midterm_2024 • Q1\nConsider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • trial_midterm • Q17\nA def square" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Generators and Iterators", + "subtopic_title": "", + "search_text": "What is the primary advantage of a generator over a list for large datasets?\nGenerators do not store the entire sequence in memory, which is essential for very large or infinite datasets.\nGenerators" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types.\nI is correct (e.g. a=1, b=2, both int). II is incorrect — if two objects have the same value " + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Operators and Truth", + "subtopic_title": "", + "search_text": "What is the result of (a//b)*b + a%b?\nArithmetic operators" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows basic list manipulation including 'append' and 'print', which are used in the question to build and display the result list." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows basic list manipulation including 'append' and 'print', which are used in the question to build and display the result list." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Defines the 'print' function, helping a student understand that the final line of the code outputs the contents of 'result'." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Demonstrates a 'for' loop that iterates through a list and uses 'append' to build a new list, mirroring the structure of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Shows basic list manipulation including 'append' and 'print', which are used in the question to build and display the result list.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Defines the 'print' function, helping a student understand that the final line of the code outputs the contents of 'result'.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Demonstrates a 'for' loop that iterates through a list and uses 'append' to build a new list, mirroring the structure of the question.", + "critical_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets do not explain the 'zip()' function or the floor division operator '//', which are critical to determining the output values (2 instead of 2.5). A student without prior knowledge would not know how 'a' and 'b' are paired or what '//' does.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets cover basic list appending and printing but completely omit the 'zip' function and the '//' arithmetic operator.", + "missing_concepts": [ + "zip() function for pairing elements", + "Floor division operator (//)", + "Unpacking multiple variables in a for loop (for a, b in ...)" + ], + "proposed_fix": "Add a key point or AI example that explicitly demonstrates zip() and basic arithmetic operators like floor division." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a Key Point: 'The zip() function pairs elements from two or more lists together (e.g., zip([1,2], [3,4]) gives (1,3) and (2,4)). The floor division operator // divides numbers and rounds down to the nearest integer.'", + "why_helpful": "Directly addresses the missing knowledge required to solve this specific exam question.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:58:12Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
            • A function is a grouping of code that can perform a certain task and can be re-used \n
            • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Which script does NOT print the correct answer for the area of a circle?\nA\nB\nC\nD\nC\nIf math is imported as constants, it must be referred to as 'constants.pi'. 'math.pi' will no longer be available unless 'math' was also imported directly." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ai-example-8", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95" + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller." + }, + { + "item_id": "ai-example-3", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "from-import binds only the imported name\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `im" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually availabl" + }, + { + "item_id": "kp-1", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import r" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-16-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-16-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather alert system." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Excluding the identical piece, this is the only snippet that touches on reversing a simple numeric list (turning [1, 2, 3, 4, 5] into [5, 4, 3, 2, 1]), which is conceptually related to the target output of the current question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Excluding the identical piece, this is the only snippet that touches on reversing a simple numeric list (turning [1, 2, 3, 4, 5] into [5, 4, 3, 2, 1]), which is conceptually related to the target output of the current question." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Mentions list variable names like 'x', though it doesn't help with slicing logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "rationale": "This piece contains the exact same question context (numbers = [1..10]), the same target result ([10, 8, 6, 4, 2]), and explicitly discusses the correct and incorrect options." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Excluding the identical piece, this is the only snippet that touches on reversing a simple numeric list (turning [1, 2, 3, 4, 5] into [5, 4, 3, 2, 1]), which is conceptually related to the target output of the current question.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Mentions list variable names like 'x', though it doesn't help with slicing logic.", + "critical_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While one identical snippet exists, the remaining candidate snippets provide zero explanation of the 'start:stop:step' slicing syntax or how negative indices work. Without the identical piece, a student with no prior knowledge cannot solve this.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate set lacks any conceptual explanation of sequence slicing (step, start, stop).", + "missing_concepts": [ + "List slicing syntax: list[start:stop:step]", + "Behavior of negative steps (e.g., ::-1 or ::-2)", + "Behavior of negative start indices (e.g., -1)", + "Chained slicing evaluation (e.g., [::-2][::-1])" + ], + "proposed_fix": "Add a foundational reference item explaining list[start:stop:step] with specific examples for common patterns like reverse and skipping items." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'List Slicing Reference' piece: 'Use list[start:stop:step] to extract parts of a list. start: beginning index; stop: end index (not included); step: number of elements to move. A negative step reverses the direction. Examples: [::-1] reverses the list; [::2] takes every second item; [-1::-2] starts at the last item and moves backwards by two.'", + "why_helpful": "Gives the student the rules to solve the question themselves rather than just matching a past question's answer.", + "why_maybe_unnecessary": "Only if the system is intended to rely purely on past exam pattern-matching.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:58:52Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Corre" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", leaving only the second occurrence replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This snippet is the only candidate that explicitly shows string slicing syntax (alphabet[1::2]), which is a fundamental concept required to evaluate Option A in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This snippet is the only candidate that explicitly shows string slicing syntax (alphabet[1::2]), which is a fundamental concept required to evaluate Option A in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet describes a string manipulation task (formatting phone numbers and removing separators), which aligns with the general theme of string cleaning and modification found in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "This snippet is the only candidate that explicitly shows string slicing syntax (alphabet[1::2]), which is a fundamental concept required to evaluate Option A in the question.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet describes a string manipulation task (formatting phone numbers and removing separators), which aligns with the general theme of string cleaning and modification found in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While one snippet shows string slicing, none of the candidates explain the 'string[start:stop]' syntax with two indices, nor do they cover the 'replace()' method's optional 'count' parameter. A student with zero Python knowledge would not be able to determine that 'index + 4' correctly offsets the length of the word 'book' or that the second 'replace' call in Option B effectively reverts only the first occurrence.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack foundational explanations for string slicing and common string methods beyond a mention of find() in the question hint.", + "missing_concepts": [ + "String slicing with start and stop indices (sentence[start:stop])", + "The 'count' parameter in the string.replace() method" + ], + "proposed_fix": "Add a concept-based snippet covering 'Common String Methods and Slicing' that demonstrates slicing, find, and replace with multiple occurrences." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet titled 'String Slicing and Methods' which provides an example of slicing a string to replace a substring and using replace(old, new, count) to limit modifications.", + "why_helpful": "This would provide the exact mechanical knowledge needed to interpret both code options provided in the multiple-choice question.", + "why_maybe_unnecessary": "The question already provides a hint for find(), so providing hints for slicing and replace might make the question too easy if not balanced.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:59:21Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the requested sentence exactly, including the word \"and\" before the final fruit. Option A joins the list as \"apple, banana, orange\" and does not produce the exact requested wording.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is the most relevant as it explicitly mentions printing a template string ('[NAME] has received a grade of [GRADE]') using variables, which is the core concept of the question's string formatting requirement." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is the most relevant as it explicitly mentions printing a template string ('[NAME] has received a grade of [GRADE]') using variables, which is the core concept of the question's string formatting requirement." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet involves string formatting for phone numbers, which provides some context for how Python handles string construction and manipulation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet is the most relevant as it explicitly mentions printing a template string ('[NAME] has received a grade of [GRADE]') using variables, which is the core concept of the question's string formatting requirement.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet involves string formatting for phone numbers, which provides some context for how Python handles string construction and manipulation.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain f-string syntax (the 'f' prefix and curly braces), list indexing (e.g., fruits[0]), or the behavior of the '.join()' method. Without knowing that '.join()' simply concatenates elements with a separator and doesn't add 'and' before the final item, a student cannot distinguish between Option A and Option B.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets completely lack fundamental information on string formatting and list access techniques required to solve the problem.", + "missing_concepts": [ + "f-strings (literal string interpolation)", + "List indexing (accessing elements by position)", + "String .join() method functionality and limitations" + ], + "proposed_fix": "Add a foundational snippet covering string manipulation basics, specifically f-strings and how to join list elements with custom logic vs. the .join() method." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'String Formatting and List Access' that explains: 1. f-strings: f'Text {variable}' for embedding values. 2. List indexing: list[0], list[1] to get specific items. 3. Comparison: Showing that ', '.join(['a', 'b', 'c']) results in 'a, b, c' without an Oxford comma or 'and'.", + "why_helpful": "This would allow a student to realize that Option B is necessary for the specific 'and' requirement and that f-strings are the correct way to interpolate variables.", + "why_maybe_unnecessary": "Basic Python syntax is often assumed, but for a 'zero-knowledge' target, this is a critical gap.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:59:55Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})", + "b": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "c": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "d": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)" + }, + "correct": "d", + "explanation": "Option D constructs one aligned series for the local parts and one for the domains, then returns them in a DataFrame with the correct column names. The other options either overwrite values, build the wrong structure, or use the wrong field names.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "This snippet explicitly teaches the syntax and concept of a function accepting a 'flexible number of arguments' (*args), which is the core requirement for the main() function signature in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "This snippet explicitly teaches the syntax and concept of a function accepting a 'flexible number of arguments' (*args), which is the core requirement for the main() function signature in the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string extraction logic (getting a TLD from a URL), which is conceptually identical to splitting an email address to get the local and domain parts as required by the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Confirms the existence and usage of 'pd.Series', helping a student identify why Option D (which uses pd.Series) is a plausible pandas-idiomatic choice." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "This snippet explicitly teaches the syntax and concept of a function accepting a 'flexible number of arguments' (*args), which is the core requirement for the main() function signature in the question.", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string extraction logic (getting a TLD from a URL), which is conceptually identical to splitting an email address to get the local and domain parts as required by the question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Confirms the existence and usage of 'pd.Series', helping a student identify why Option D (which uses pd.Series) is a plausible pandas-idiomatic choice.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the necessary pieces to understand the function signature (*args) and the string manipulation (split). However, they lack an example of list comprehensions and the specific pandas constructor 'pd.DataFrame(dict_of_lists)', which makes it difficult to definitively rule out Option B (which incorrectly overwrites dict values) without prior knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "While the fundamental building blocks (args, splitting, pandas context) are present, the complex construction of a DataFrame from list comprehensions is not represented.", + "missing_concepts": [ + "List comprehensions", + "Constructing a pandas DataFrame from a dictionary of lists or Series" + ], + "proposed_fix": "Add a snippet demonstrating basic list comprehension syntax and the standard way to create a DataFrame from a dictionary: pd.DataFrame({'col': [val1, val2]})." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: df = pd.DataFrame({'column_a': [list], 'column_b': [list]}).", + "why_helpful": "This would allow the student to see that Option D follows the standard pattern for creating multi-row DataFrames, whereas Option B's loop-assignment pattern only preserves one row.", + "why_maybe_unnecessary": "A student might guess Option D is 'more complete' due to the use of Series and list comprehensions, but a direct example is safer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:00:25Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q16", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "False\nTrue", + "c": "False\nFalse", + "d": "True\nFalse" + }, + "correct": "a", + "explanation": "The object is created with name 'John Smith', and because no gender argument is passed, the default value 'not specified' is used. Both comparisons therefore evaluate to True.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the blueprint for understanding class constructors (__init__) and how attributes like 'name' are mapped to the object during initialization, which is the core structure of the Employee class in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the blueprint for understanding class constructors (__init__) and how attributes like 'name' are mapped to the object during initialization, which is the core structure of the Employee class in the question." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "This is critical for understanding the 'default value' mechanic. It explicitly states that when an argument is omitted, the default value (like y=11 in the snippet or gender='not specified' in the question) is used." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the blueprint for understanding class constructors (__init__) and how attributes like 'name' are mapped to the object during initialization, which is the core structure of the Employee class in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "This is critical for understanding the 'default value' mechanic. It explicitly states that when an argument is omitted, the default value (like y=11 in the snippet or gender='not specified' in the question) is used.", + "critical_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The student can use the OOP snippet to understand how attributes are set and the Arguments snippet to understand how the omitted 'gender' parameter is handled. The combination covers all mechanics required to determine that both print statements evaluate to True.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic is present across two different topics (OOP and Functions), there isn't a single item that demonstrates default values specifically within an __init__ method.", + "missing_concepts": [ + "default parameter values in class constructors" + ], + "proposed_fix": "Add a targeted snippet or key point that shows a class definition where the constructor uses default values for optional attributes." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'OOP: Default Arguments in Constructors' showing: class User: def __init__(self, username, status='active'): self.username = username; self.status = status.", + "why_helpful": "It directly bridges the gap between general function arguments and OOP attribute initialization, making the logic more intuitive for a beginner.", + "why_maybe_unnecessary": "A student who understands default arguments in functions can usually generalize that knowledge to methods, but an explicit example reduces cognitive load.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:00:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original expression computes the number of days between January 10 and January 1, then adds 1, which yields 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "kp-8", + "rationale": "While it doesn't cover the datetime module, it contains key point kp-8 which identifies the 'Which code fragment prints the SAME output as...?' question pattern common in these exams." + }, + "top_three_snippets": [ + { + "item_id": "kp-8", + "rationale": "While it doesn't cover the datetime module, it contains key point kp-8 which identifies the 'Which code fragment prints the SAME output as...?' question pattern common in these exams." + }, + { + "item_id": "ks-df3b849d59", + "rationale": "Provides meta-knowledge about exam question types, including the 'same output' variety, helping the student recognize the task structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This past exam piece explicitly explains that subtracting two datetime objects results in a timedelta, that .days provides the difference as an integer, and that adding 1 is part of the logic to calculate the day of the year. This is the exact logic required to evaluate the question." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "rationale": "While it doesn't cover the datetime module, it contains key point kp-8 which identifies the 'Which code fragment prints the SAME output as...?' question pattern common in these exams.", + "critical_piece_ids": [ + "kp-8" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-df3b849d59", + "rationale": "Provides meta-knowledge about exam question types, including the 'same output' variety, helping the student recognize the task structure.", + "critical_piece_ids": [ + "ks-df3b849d59" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "Excluding the near-identical past exam piece, there is zero information in the candidate snippets regarding the 'datetime' module, 'strptime' formatting, or datetime subtraction mechanics. The question is unanswerable with general snippets alone.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate set lacks a core conceptual snippet for the Datetime topic (Week 6), which is necessary to understand object constructors and formatting.", + "missing_concepts": [ + "datetime.strptime format codes (e.g., %Y/%m/%d)", + "datetime object constructor: datetime(year, month, day)", + "the result of subtracting datetimes is a timedelta object", + "timedelta .days attribute" + ], + "proposed_fix": "Add a new snippet family for 'Datetime Core' that provides an example of strptime, object creation, and subtraction." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Basics' snippet. Example: `from datetime import datetime; dt = datetime.strptime('2023/1/10', '%Y/%m/%d'); diff = (dt - datetime(2023, 1, 1)).days`. Explain that strptime parses strings, datetime() creates objects, and subtraction gives days difference.", + "why_helpful": "This would provide the necessary syntax and semantic knowledge for the student to solve any datetime-math question without relying on finding a near-identical exam question.", + "why_maybe_unnecessary": "Only unnecessary if we assume students will always have access to the sample final exam piece which already contains the explanation.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:01:23Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "kp-8", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Which code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others." + }, + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Basic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step g" + }, + { + "item_id": "ai-example-7", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Negative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: star" + }, + { + "item_id": "kp-6", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Syntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "List is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]\nImmutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the sam" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Two names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True\nAssignment binds the left-hand name to the object produced on the right-hand side." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-3-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-midterm_2023-3-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Which other program will give the same output as the following code snippet?" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-22-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2024-22-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?\nA z = [[\"a\", \"b\", \"c\"], [1, 2, 3, 4]]\nprint(z[0][1] + str(z[1][3])*3)\nB print('b'+ str(8 % 4)*3)\nC print('b' + str(" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-5-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-midterm_2024-5-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Which other program will produce the same output as the following code snippet?" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-5-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 !" + } + ] + }, + { + "snippet_id": "item:ks-df3b849d59", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "ks-df3b849d59", + "item_type": "source_lecture", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Exam question types\nWhich code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others. / Which correctly solves the problem? Option" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-extra_practice-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modif" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "Multiple choice", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df[['Player', 'Age']])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df.loc[:, 'Age'])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing in this form does not accept the tuple (1, 'Age') to select a single cell.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is categorized under 'Inspecting and Selecting Data', which is the exact topic of the question. Although the snippet text is truncated, it is the most relevant logical container for the required knowledge." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is categorized under 'Inspecting and Selecting Data', which is the exact topic of the question. Although the snippet text is truncated, it is the most relevant logical container for the required knowledge." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers basic Pandas structure and implies column selection syntax (df['A']), which provides a starting point for understanding how DataFrames are accessed." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is categorized under 'Inspecting and Selecting Data', which is the exact topic of the question. Although the snippet text is truncated, it is the most relevant logical container for the required knowledge.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Covers basic Pandas structure and implies column selection syntax (df['A']), which provides a starting point for understanding how DataFrames are accessed.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets fail to explain the rules for .loc selection, double-bracket column selection, or the fact that standard bracket indexing df[row, col] is invalid. A student cannot determine that option (d) is the error without these specific Pandas indexing rules.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Critical Pandas indexing syntax rules are missing.", + "missing_concepts": [ + "Pandas .loc accessor for label-based indexing", + "List-based column selection df[['col1', 'col2']]", + "Syntax limitations of standard bracket indexing (df[] only accepts single keys or slices, not row-column tuples)", + "Boolean indexing in Pandas" + ], + "proposed_fix": "Add a 'Pandas Data Selection Guide' snippet that explicitly compares df[...], df.loc[...], and df.iloc[...] and lists common syntax errors." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "New snippet: 'Pandas Selection & Indexing'. Content: 1. Column selection: df['col'] or df[['c1', 'c2']]. 2. Label selection: df.loc[rows, cols]. 3. Integer selection: df.iloc[rows, cols]. 4. Common Error: df[row, col] is invalid; you must use .loc or .iloc for multi-axis indexing.", + "why_helpful": "Provides the exact rules needed to validate options A, B, and C, and identify D as the error.", + "why_maybe_unnecessary": "Only if the student is expected to have prior experience with Pandas syntax, which contradicts the 'zero knowledge' goal.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:02:00Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "animals methods", + "question": "You have the following definition for a class called Animals:\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs = True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin = True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "def walk():\n return sound if legs else 'Cannot walk!'\ndef swim():\n return sound if fin else 'Cannot swim!'", + "d": "def walk():\n if legs == True:\n return sound\n else:\n return 'Cannot walk!'\ndef swim():\n if fin == True:\n return sound\n else:\n return 'Cannot swim!'" + }, + "correct": "a", + "explanation": "Option A is the only choice that defines both instance methods with self and correctly returns self.sound when the corresponding boolean attribute is truthy, otherwise the required fallback string.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet directly addresses the concept of adding a 'method' (specifically a 'compare' method) to an existing class to perform logic based on attributes, which is the exact task required by the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet directly addresses the concept of adding a 'method' (specifically a 'compare' method) to an existing class to perform logic based on attributes, which is the exact task required by the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Explains the definition of classes and attributes (like 'name' and 'mode'), which parallels the 'legs', 'fin', and 'sound' attributes used in the Animals class." + }, + { + "item_id": "aiq-4", + "rationale": "Provides essential context on return behavior (ensuring a value is returned) and boolean logic (True == 1), which helps in evaluating the truthiness of attributes like 'self.legs'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet directly addresses the concept of adding a 'method' (specifically a 'compare' method) to an existing class to perform logic based on attributes, which is the exact task required by the question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Explains the definition of classes and attributes (like 'name' and 'mode'), which parallels the 'legs', 'fin', and 'sound' attributes used in the Animals class.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Provides essential context on return behavior (ensuring a value is returned) and boolean logic (True == 1), which helps in evaluating the truthiness of attributes like 'self.legs'.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The current snippets describe the task of writing methods and attributes but do not show the actual Python syntax for instance methods. A student with zero knowledge would not know that they must include 'self' as an argument or use 'self.attribute' to access variables. Options A/B and C/D are distinguished solely by this 'self' syntax, which is never explicitly shown in the provided candidate pieces.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a total absence of code examples showing how to define a method within a class and how to reference instance attributes using 'self'.", + "missing_concepts": [ + "Method definition syntax: def method_name(self):", + "Instance attribute access: self.attribute_name", + "Ternary operator syntax: value_if_true if condition else value_if_false" + ], + "proposed_fix": "Add a new snippet to the OOP Fundamentals topic that provides a clear code example of a class method returning an attribute value." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet Label: 'Class Method Syntax'. Content: 'When defining a method inside a class, the first argument must always be 'self' (e.g., def walk(self):). Inside the method, you access the object's attributes using 'self.attribute_name'. Example: return self.sound if self.legs else \"None\".'", + "why_helpful": "This provides the specific syntax needed to distinguish between the correct 'self'-based methods (Option A) and the incorrect standalone-style functions (Option C).", + "why_maybe_unnecessary": "Only if other OOP snippets are updated to include actual code blocks instead of just descriptions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:02:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q20", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "movie review methods", + "question": "You have the following definition for a class named Movie.\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute,\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and return the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segments will work as intended." + }, + "correct": "d", + "explanation": "Option A is broken because add_review uses list-plus-number syntax and compare immediately returns on the first loop iteration, so it never returns other.title when the other movie has the higher rating. Option B is also broken because add_review and rating are missing self and compare compares method objects instead of calling them.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This family contains multiple AI examples that directly address the bugs in the question: how to correctly append to lists (vs +=), how to call methods with parentheses, and the requirement for 'self' in method definitions." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "This family contains multiple AI examples that directly address the bugs in the question: how to correctly append to lists (vs +=), how to call methods with parentheses, and the requirement for 'self' in method definitions." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows a standard class definition and initialization, helping the student recognize the structure of the provided code context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "The search text describes an identical 'compare' method requirement for a Book class based on average review scores, which is the exact logic tested here for the Movie class." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "This family contains multiple AI examples that directly address the bugs in the question: how to correctly append to lists (vs +=), how to call methods with parentheses, and the requirement for 'self' in method definitions.", + "critical_piece_ids": [ + "manual-oop-state-compare", + "manual-oop-compare-none-case", + "ai-example-6" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Shows a standard class definition and initialization, helping the student recognize the structure of the provided code context.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "", + "needed_piece_ids": [ + "manual-oop-state-compare", + "manual-oop-compare-none-case", + "ai-example-6" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The AI examples in the 'best_snippet_family' explicitly show 'self.scores.append(score)' (proving Option A's += is wrong), 'self.average()' with parentheses (proving Option B's comparison of method objects is wrong), and 'def method(self, ...)' (proving Option B's missing self is wrong).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are very strong. The only minor gap is an explicit explanation that 'list += integer' causes a TypeError, though the 'append' example provides the correct alternative.", + "missing_concepts": [ + "explicit warning about list += integer behavior" + ], + "proposed_fix": "Add a note to an AI example or key point clarifying that adding a single item to a list requires .append(), while += expects another iterable." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "manual-oop-state-compare", + "proposal": "Add a comment: # Note: use .append(x), not += x which only works for adding another list.", + "why_helpful": "Directly helps the student identify the bug in Option A where 'self.reviews += score' is used.", + "why_maybe_unnecessary": "The correct use of .append() in the example is already a strong hint.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:03:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-oop-compare-none-case", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Return `None` when neither object clearly wins\nclass Book:\n def __init__(self, title, scores):\n self.title = title\n self.scores = scores\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def winner_against(self, other):\n if se" + }, + { + "item_id": "manual-oop-state-compare", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.sc" + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`." + }, + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` is passed automatically in method calls\nclass Clock:\n def set_hour(self, hour):\n self.hour = hour\n\nc = Clock()\nc.set_hour(9)\n# c.set_hour(c, 9) # wrong: passes one argument too many\nWriting `obj.method(x)` already passes `self` for you. Inside the method, store " + }, + { + "item_id": "manual-oop-init-defaults", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "datetime weekly dates list", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "b": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "c": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "d": "This code segment will work as intended." + }, + "correct": "c", + "explanation": "After the first append, the newly added element is a formatted string, so on the next loop iteration the code tries to add a timedelta to a string instead of to a datetime object.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "This is the only snippet that discusses how Python handles types and values (e.g., bool/int interactions), which is the closest relevant concept to the type-mismatch error in the question, although it does not cover the datetime library specifically." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "This is the only snippet that discusses how Python handles types and values (e.g., bool/int interactions), which is the closest relevant concept to the type-mismatch error in the question, although it does not cover the datetime library specifically." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "While highly insufficient, it provides a general precedent for thinking about return values and type interactions." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "This is the only snippet that discusses how Python handles types and values (e.g., bool/int interactions), which is the closest relevant concept to the type-mismatch error in the question, although it does not cover the datetime library specifically.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "While highly insufficient, it provides a general precedent for thinking about return values and type interactions.", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the provided snippets mention the 'datetime' or 'timedelta' modules. A student with zero prior Python knowledge would have no way of knowing that strftime() returns a string or that adding a timedelta to a string results in a TypeError without specific documentation on these classes and methods.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippet bank is completely missing coverage of the standard 'datetime' library, specifically the return types of its core methods and compatibility with 'timedelta'.", + "missing_concepts": [ + "datetime.strptime return type (datetime object)", + "datetime.strftime return type (string)", + "timedelta addition rules (only works with datetime/date/time objects, not strings)" + ], + "proposed_fix": "Add a new snippet family covering common standard library modules like 'datetime', including examples of format conversion and arithmetic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Standard Library: Datetime' snippet showing: 1. Converting strings to datetime (strptime). 2. Adding/subtracting time (timedelta). 3. Converting datetime back to strings (strftime). Explicitly note that strftime returns a string which cannot be used for further math.", + "why_helpful": "This directly addresses the logic gap in the question where the student must distinguish between a datetime object and its string representation.", + "why_maybe_unnecessary": "Only unnecessary if 'datetime' is considered 'prior knowledge', but the prompt assumes 'almost zero prior Python knowledge'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:03:31Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "pandas date column from day month year", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A correctly constructs datetime objects in year-month-day order from the three columns and then formats them into the requested DD-MM-YYYY strings.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet demonstrates creating a new Series from existing data via a transformation (.map/split), which matches the high-level pattern of transforming columns to create a new one." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet demonstrates creating a new Series from existing data via a transformation (.map/split), which matches the high-level pattern of transforming columns to create a new one." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows how to use zip() to iterate over multiple sequences simultaneously, which is the mechanism used in the correct answer's list comprehension." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet demonstrates creating a new Series from existing data via a transformation (.map/split), which matches the high-level pattern of transforming columns to create a new one.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows how to use zip() to iterate over multiple sequences simultaneously, which is the mechanism used in the correct answer's list comprehension.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the structural components (new column creation, zip) are partially covered, there is absolutely no information on the 'datetime' module, the specific argument order for the datetime constructor (year, month, day), or the 'strftime' vs 'strptime' methods and their format codes. A student would not be able to distinguish between options A, B, and C.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Major gap in datetime module coverage and string formatting for dates.", + "missing_concepts": [ + "datetime.datetime constructor (year, month, day) order", + "strftime vs strptime", + "Format codes like %d, %m, %Y" + ], + "proposed_fix": "Add a 'Working with Dates' snippet or detail piece explaining the datetime constructor and basic strftime formatting." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet for 'Python Datetime Module' that explains: 1. datetime(year, month, day) initialization, 2. .strftime() for formatting dates to strings, 3. common codes like %Y, %m, %d.", + "why_helpful": "This is essential for any question involving date manipulation, which is common in pandas exams.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:04:01Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "pandas above average salary", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame:\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 1000\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "None of the blocks of code will work as intended.", + "c": "Both blocks of code will work as intended.", + "d": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])" + }, + "correct": "a", + "explanation": "Option A correctly computes the mean salary, builds both required columns, and prints the full DataFrame filtered to rows where Above_average is True. Option D does not print the result in the required way because it filters only on Salary_difference > 0 rather than explicitly using the Above_average column requested in the specification.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Directly addresses calculating values in a Series relative to the mean, which is the core logic for Operation 2 and 3." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Directly addresses calculating values in a Series relative to the mean, which is the core logic for Operation 2 and 3." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows the fundamental syntax for creating a new column in an existing DataFrame by assignment." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Explains boolean masking/filtering in Pandas, which is necessary to identify rows matching the criteria in Operation 3." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Directly addresses calculating values in a Series relative to the mean, which is the core logic for Operation 2 and 3.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows the fundamental syntax for creating a new column in an existing DataFrame by assignment.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Explains boolean masking/filtering in Pandas, which is necessary to identify rows matching the criteria in Operation 3.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the logic for mean calculation, column creation, and filtering is present, the specific use of list comprehension to build a Series (Option A) or .map(lambda) (Option D) is not explicitly demonstrated in a Pandas context.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is no snippet demonstrating how to use conditional logic (like list comprehension or lambda functions) to populate a new Pandas column.", + "missing_concepts": [ + "Conditional column creation with list comprehension in Pandas", + "Using .map(lambda...) for element-wise Series transformation" + ], + "proposed_fix": "Add a snippet showing: df['Is_Above'] = [True if x > threshold else False for x in df['Col']]." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a piece to 'Pandas Core Structures' demonstrating: df['Result'] = [True if x > threshold else False for x in df['A']].", + "why_helpful": "This pattern is exactly what Option A uses to create the Above_average column.", + "why_maybe_unnecessary": "Standard list comprehension is a basic Python concept, but its integration with Pandas Series creation is non-trivial for beginners.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:04:34Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "question_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24", + "exam_id": "resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "pandas lambda output", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "b": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "c": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15", + "d": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18" + }, + "correct": "d", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing C values 16, 17, and 18.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions that the .map() method allows applying a function, which is the core mechanism used in the question to transform column 'A'." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions that the .map() method allows applying a function, which is the core mechanism used in the question to transform column 'A'." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Helps the student understand the context of creating a new column 'C' from existing columns 'A' and 'B' in a pandas DataFrame." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides an example of a more complex transformation on a Series (like a column) involving a mean calculation, similar to the sum() used here." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions that the .map() method allows applying a function, which is the core mechanism used in the question to transform column 'A'.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Helps the student understand the context of creating a new column 'C' from existing columns 'A' and 'B' in a pandas DataFrame.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides an example of a more complex transformation on a Series (like a column) involving a mean calculation, similar to the sum() used here.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain that .map() applies a function and how to create new columns. However, there is no explicit explanation of 'lambda x:' syntax or the '.sum()' method behavior within a map context, which are critical for calculating the exact values.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The student lacks documentation on lambda functions and the pandas .sum() method.", + "missing_concepts": [ + "lambda functions", + "pandas .sum() method", + "scope of variables inside map functions" + ], + "proposed_fix": "Add a snippet explaining lambda functions as anonymous functions and another showing common pandas aggregation methods like .sum()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Lambda Functions. Text: A lambda function is a small anonymous function. Syntax: 'lambda arguments : expression'. Example: 'lambda x : x + 10' adds 10 to the input x.", + "why_helpful": "Directly explains the 'lambda x: x + ...' part of the code.", + "why_maybe_unnecessary": "Some students might infer it from the context of 'applying a function', but it's a significant jump.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Pandas Aggregations. Text: df['Col'].sum() calculates the total sum of all values in that column. This result is a single number.", + "why_helpful": "Explains that df['B'].sum() equals 15 (4+5+6), which is added to each element of A.", + "why_maybe_unnecessary": "Sum is a common English word, but its behavior on a Series/Column should be explicit.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:04:46Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:cs-b46633d18d", + "snippet_label": "Combining Data", + "week": 5, + "topic": "Combining Data", + "pieces": [ + { + "item_id": "cs-b46633d18d", + "item_type": "source_notebook", + "bucket": "recommended", + "topic": "Combining Data", + "subtopic_title": "", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noo" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q01", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q01", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_1", + "question": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?", + "options": { + "a": "print(x[0][1] * x[-3][0] == x[2][1])", + "b": "print(x[1][0] + x[-2][0] == x[-1][1])", + "c": "print(x[-1][0] - x[-2][0] == x[0][1])", + "d": "All lines of code will print True." + }, + "correct": "d", + "explanation": "The three code lines evaluate to 2 * 3 == 6, 3 + 5 == 8, and 7 - 5 == 2, so each one is True. Therefore the correct choice is that all lines print True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the only non-identical snippet that mentions indices/order (sorting) and 'stepping backwards', which is the closest conceptual link to negative indexing, though it is still insufficient." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the only non-identical snippet that mentions indices/order (sorting) and 'stepping backwards', which is the closest conceptual link to negative indexing, though it is still insufficient." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Helps conceptualize a list containing other structures (dictionaries instead of tuples), which is useful for understanding nested access." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Contains the exact question, the list definition, and a step-by-step breakdown of the arithmetic logic." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Contains the same question structure and the identical evaluation logic (e.g., 2 * 3 == 6)." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the only non-identical snippet that mentions indices/order (sorting) and 'stepping backwards', which is the closest conceptual link to negative indexing, though it is still insufficient.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Helps conceptualize a list containing other structures (dictionaries instead of tuples), which is useful for understanding nested access.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While the identical question exists in the library, there is no general-purpose snippet that explains the rules of 0-based indexing, negative indexing (x[-1]), or double-indexing into nested tuples (x[i][j]). Without the identical question, a student with zero knowledge could not derive the answer.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Major gap in foundational syntax for accessing elements in sequences and nested structures.", + "missing_concepts": [ + "0-based indexing", + "Negative indexing (counting from the end of a list)", + "Accessing elements within nested structures (list of tuples)" + ], + "proposed_fix": "Add a 'General Concept' or 'Cheat Sheet' snippet for Python Indexing that explicitly demonstrates positive vs. negative indices and how to index into a list of tuples." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Python Indexing & Nested Access'. It should show: 1) Indexing basics (x[0] is first). 2) Negative indexing (x[-1] is last). 3) Nested access (if x = [(a, b)], then x[0][1] is b).", + "why_helpful": "This provides the mechanical 'lookup rules' needed to solve arithmetic-based indexing questions without relying on having seen the exact question before.", + "why_maybe_unnecessary": "If the goal is only to pass by recognizing identical past exam questions, the current library is enough.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:05:35Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q02", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q02", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_1", + "question": "Executing the following program will produce an error. Why?\n\ndef power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)", + "options": { + "a": "Result is a local name that cannot be referenced outside of the function power.", + "b": "** is not a valid Python operator.", + "c": "The syntax used in the return statement to format the string is incorrect.", + "d": "The function called power should not return the string 'The result of {} ** {} is: {}.'.format(num, factor, result), but the value of result." + }, + "correct": "a", + "explanation": "`result` is defined inside the function, so it has local scope. The line `print(result)` is outside the function and therefore cannot access that local variable.", + "code_context": "def power(num, factor):\n result = num ** factor\n return 'The result of {} ** {} is: {}.'.format(num, factor, result)\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Provides the formal definition of 'local names' (defined inside a function) and explicitly states they are 'only known inside the function', which is the core concept tested." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the formal definition of 'local names' (defined inside a function) and explicitly states they are 'only known inside the function', which is the core concept tested." + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "Reinforces that local names are 'gone after function ends' and that functions 'leave no traces'." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Shows another example of variable accessibility across different scopes (func_1 vs func_2)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "ks-00b2983ca8", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "rationale": "Matches the exact code logic, function name (power), and variable name (result) as the question." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Identical code pattern and explanation regarding the local scope of 'result' in 'power'." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "Identical logic using a 'cube' function instead of 'power', but with the same 'result' variable scope error." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "Provides the formal definition of 'local names' (defined inside a function) and explicitly states they are 'only known inside the function', which is the core concept tested.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-00b2983ca8", + "rationale": "Reinforces that local names are 'gone after function ends' and that functions 'leave no traces'.", + "critical_piece_ids": [ + "ks-00b2983ca8" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Shows another example of variable accessibility across different scopes (func_1 vs func_2).", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-2-w3-scope" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:ks-00b2983ca8", + "rationale": "", + "needed_piece_ids": [ + "ks-00b2983ca8" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The lecture snippets clearly define that variables assigned inside a function are local and inaccessible outside. Several past exam questions provide identical patterns.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are excellent and cover both the theory and direct practical application.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:05:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:ks-00b2983ca8", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "ks-00b2983ca8", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Return statement\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.\nReturning a tuple (multiple values)\ndef po" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q03", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q03", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_3", + "question": "What will be printed by the following code segment?\n\ndef main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)", + "options": { + "a": "['a', 'None', '123']", + "b": "[[]]", + "c": "[None]", + "d": "[]" + }, + "correct": "b", + "explanation": "The function appends only elements whose type matches the type of `x`, which is `list`. Among the provided elements, only `[]` is itself a list, so the printed result is `[[]]`.", + "code_context": "def main(x):\n y = list()\n for i in x:\n if type(i) == type(x):\n y.append(i)\n return y\n\nresult = main(['a', 'None', [], {}, '123', 0.05, 111])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Explains the concept of checking types (int, float, string) within a function, which is the core principle needed to solve the question without seeing the exact problem beforehand." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Explains the concept of checking types (int, float, string) within a function, which is the core principle needed to solve the question without seeing the exact problem beforehand." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Introduces basic list operations like .append(), which is used in the code segment." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a common pattern of iterating through a list and appending items to a new list based on a condition." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Provides the type-checking conceptual framework." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Covers list instantiation and the append method." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "rationale": "This snippet contains the exact logic and explanation for this question, identifying that type(x) is list and only [] matches." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Matches the question logic exactly, confirming that only the empty list [] in the input matches the type of the container list." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Explains the concept of checking types (int, float, string) within a function, which is the core principle needed to solve the question without seeing the exact problem beforehand.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Introduces basic list operations like .append(), which is used in the code segment.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a common pattern of iterating through a list and appending items to a new list based on a condition.", + "critical_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "Provides the type-checking conceptual framework.", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Covers list instantiation and the append method.", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "While the exact question is present in two snippets, even excluding them, the 'trial-final-exam' snippet clearly explains how Python differentiates between types (int vs float vs string), allowing a student to deduce that type(list) will only match other list objects.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main gap is an explicit map of literals to their types (e.g., that [] is a list and {} is a dict).", + "missing_concepts": [ + "Literal syntax for empty containers (list vs dict vs tuple)" + ], + "proposed_fix": "Add a foundational snippet that shows examples of basic types: list=[], dict={}, set=set(), tuple=()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A 'Cheat Sheet: Python Types' snippet showing: x = [] # list, x = {} # dict, x = 'a' # str, x = 1 # int.", + "why_helpful": "It would remove the need for students to guess what the symbols [] and {} represent, which is critical for this specific 'type(i) == type(x)' check.", + "why_maybe_unnecessary": "Several exam snippets indirectly mention [] is a list, but a dedicated reference is clearer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:06:24Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q04", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q04", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_3", + "question": "Suppose you have the following function, which takes two integers as arguments:\n\ndef main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table\n\nWhat will be printed by the following line of code:\nprint(main(1))", + "options": { + "a": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10']", + "b": "['1 * 1 = 1', '1 * 2 = 2', '1 * 3 = 3', '1 * 4 = 4', '1 * 5 = 5', '1 * 6 = 6', '1 * 7 = 7', '1 * 8 = 8', '1 * 9 = 9', '1 * 10 = 10', '1 * 11 = 11']", + "c": "This code produces an error as there is a missing argument when calling main.", + "d": "The code produces a syntax error because of the line:\n table.append(f'{x} * {i} = {x*i}')" + }, + "correct": "a", + "explanation": "When `main(1)` is called, `y` uses its default value `11`. The loop runs for `i` values 1 through 10, so it returns a list of ten multiplication strings from `1 * 1 = 1` through `1 * 10 = 10`.", + "code_context": "def main(x, y=11):\n table = []\n i = 1\n while i < y:\n table.append(f'{x} * {i} = {x*i}')\n i += 1\n return table" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet provides a clear example of how default argument values (e.g., num2 = 10) are utilized when a function is called with fewer arguments than defined." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet provides a clear example of how default argument values (e.g., num2 = 10) are utilized when a function is called with fewer arguments than defined." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Reinforces the concept of optional keyword arguments having default values, which is the core mechanic being tested." + }, + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a function definition with a default argument (condition=lambda x: x), illustrating the syntax in a slightly more complex context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This piece contains the exact same code, question, and logic regarding the default argument y=11 and the while loop range." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "This piece is an identical copy of the question, explicitly explaining that y defaults to 11 and the loop runs while i < 11." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet provides a clear example of how default argument values (e.g., num2 = 10) are utilized when a function is called with fewer arguments than defined.", + "critical_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "Reinforces the concept of optional keyword arguments having default values, which is the core mechanic being tested.", + "critical_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "Shows a function definition with a default argument (condition=lambda x: x), illustrating the syntax in a slightly more complex context.", + "critical_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The database contains two identical past exam questions. Even excluding those, the concepts of default arguments and loop boundaries (i < y) are well-covered by the recommended 'Arguments' snippets.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While default arguments are well-represented, there is a minor gap in explicitly explaining f-string syntax (f'{x} * {i}') for a student with zero knowledge, though it is usually intuitive.", + "missing_concepts": [ + "f-string string formatting syntax" + ], + "proposed_fix": "Add a small reference snippet explaining that f-strings replace {variable} with the variable's value inside a string." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining f-strings: 'f-strings allow you to embed expressions inside string literals using curly braces, e.g., f\"{x} * {i}\" evaluates to the values of x and i joined by an asterisk.'", + "why_helpful": "It ensures a student doesn't get distracted by the syntax in option 'd' which claims a syntax error.", + "why_maybe_unnecessary": "Most students correctly guess f-string behavior, and the primary difficulty is the default argument.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:06:46Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. C" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-12-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-12-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA [10, 20, 30, 40, 1, 2, 3, 4]\nB [11, 22, 33, 44]\nC This code will result in an error because you cannot " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q05", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q05", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "Functions Built-in", + "question": "Suppose you have a list called x, where:\n\nx = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]", + "options": { + "a": "y = list(set(x))\nprint(sorted(y, reverse = True))", + "b": "print(x[::-2])", + "c": "Both lines of code will print that output.", + "d": "Neither line of code will print that output." + }, + "correct": "c", + "explanation": "Both snippets produce [5, 4, 3, 2, 1]. The first removes duplicates and sorts the unique values in reverse order, and the second slices every second element from the reversed list.", + "code_context": "x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Outside of the direct exam matches, this is the only snippet that provides a hint about list slicing syntax with a step (e.g., [1::2]), which is crucial for understanding Option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Outside of the direct exam matches, this is the only snippet that provides a hint about list slicing syntax with a step (e.g., [1::2]), which is crucial for understanding Option B." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "While the specific logic differs, it covers the 'Lists and Sets' topic and demonstrates indexing and logical comparisons within list structures." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "This piece is a near-identical match for the question, providing the same variable x, options A and B, and explaining why both produce the expected list." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This piece matches the question exactly and specifically explains how set() removes duplicates and how the backward slicing step functions." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Outside of the direct exam matches, this is the only snippet that provides a hint about list slicing syntax with a step (e.g., [1::2]), which is crucial for understanding Option B.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "While the specific logic differs, it covers the 'Lists and Sets' topic and demonstrates indexing and logical comparisons within list structures.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of near-identical past exam questions makes the answer certain. A student would only need to read the explanation in either the 'Functions and Imports' or 'Lists and Sets' exam snippets to identify 'c' as the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The answerability relies almost entirely on leaked exam questions. There are no general-purpose snippets explaining set conversion, the sorted() function's reverse parameter, or the behavior of negative step slicing.", + "missing_concepts": [ + "set()", + "sorted(..., reverse=True)", + "list() conversion", + "Negative step slicing ([::-2])" + ], + "proposed_fix": "Add general documentation snippets for 'Built-in Functions (set, list, sorted)' and 'Slicing Advanced Patterns'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Documentation for built-in collection functions explaining how set() removes duplicates and how sorted() handles the reverse=True parameter.", + "why_helpful": "Allows students to solve Option A through conceptual knowledge rather than pattern-matching against past exams.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A guide on slicing syntax focusing on the 'step' parameter, particularly negative steps like [::-1] (reverse) and [::-2] (reverse and skip).", + "why_helpful": "Provides the mechanical logic for Option B.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:07:57Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q06", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q06", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "Function Flexible Argument", + "question": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?", + "options": { + "a": "def main(**kwargs):\n total = 0\n for item, price in kwargs.items():\n total += item\n return total", + "b": "def main(**kwargs):\n total = 0\n for price in kwargs.values():\n total += price\n return total", + "c": "def main(**kwargs):\n total = 0\n for item, price in kwargs.keys():\n total += price\n return total", + "d": "All functions will return the intended value." + }, + "correct": "b", + "explanation": "B sums the keyword argument values, which is exactly what the function should do. A incorrectly adds the keyword names, and C iterates over keys in a way that does not match the intended structure.", + "code_context": "def main(**kwargs):\n # Sum the values passed as keyword arguments" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Directly demonstrates a function using flexible keyword arguments (**kwargs) and explains that it captures 'key-value pairs'." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "rationale": "Directly demonstrates a function using flexible keyword arguments (**kwargs) and explains that it captures 'key-value pairs'." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduces the concept of 'flexible number of arguments' and provides a similar summing logic context, even though it uses *args." + }, + { + "item_id": "aiq-2", + "rationale": "Provides general context for dictionaries and mappings, helping a student realize that **kwargs behaves like a dictionary." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "Exact same question regarding summing keyword argument values in a function named main." + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Exact same question (Resit variant) with identical logic and examples." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "rationale": "Directly demonstrates a function using flexible keyword arguments (**kwargs) and explains that it captures 'key-value pairs'.", + "critical_piece_ids": [ + "exam-midterm_2023-10-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "Introduces the concept of 'flexible number of arguments' and provides a similar summing logic context, even though it uses *args.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:aiq-2", + "rationale": "Provides general context for dictionaries and mappings, helping a student realize that **kwargs behaves like a dictionary.", + "critical_piece_ids": [ + "aiq-2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list contains two instances of the exact past exam question, which provides the full answer. Even without those, the midterm_2023 snippet explains the keyword argument structure well enough for an educated guess.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the identical question is present, the conceptual snippets lack a clear explanation of dictionary iteration methods (.values(), .items(), .keys()).", + "missing_concepts": [ + "dict.values()", + "dict.items()", + "dictionary iteration patterns" + ], + "proposed_fix": "Add an AI-generated snippet or common question that explicitly contrasts the output of dictionary iteration methods to help distinguish why .values() is used for summing values vs .items() for key-value pairs." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Accessing Dictionary Data: keys, values, and items' showing: 'for k in d' (keys), 'for v in d.values()' (values only), and 'for k, v in d.items()' (both).", + "why_helpful": "This allows a student to understand why Option B is correct and why Option A (using items incorrectly) or Option C (invalid iteration) are wrong.", + "why_maybe_unnecessary": "The student can find the answer via the identical past exam questions already in the bank.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:08:38Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 29, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Which update makes `library['books'] = 6` and adds `library['years']`?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q8" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q07", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q07", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries Comprehension", + "question": "Assume you already have a list of strings called words.\n\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "word_lengths = {length: word for word, length in enumerate(words)}", + "b": "word_lengths = {len: word for word in words}", + "c": "word_lengths = {word: len(word) for word in words}", + "d": "word_lengths = {len: word for word, len in words}" + }, + "correct": "c", + "explanation": "The dictionary comprehension in C maps each word to its length. The other options either reverse the key/value order or use invalid comprehension logic.", + "code_context": "words = ['example', 'python', 'exam']" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Conceptualizes the task of mapping keys (names) to values (ages) from existing lists, which helps understand the desired dictionary structure (key: value)." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Conceptualizes the task of mapping keys (names) to values (ages) from existing lists, which helps understand the desired dictionary structure (key: value)." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Reinforces the concept of keys and values by providing another mapping example (vowels to ASCII values)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This item is word-for-word identical to the target question." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Conceptualizes the task of mapping keys (names) to values (ages) from existing lists, which helps understand the desired dictionary structure (key: value).", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Reinforces the concept of keys and values by providing another mapping example (vowels to ASCII values).", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "An identical question exists in the past exams. Without it, the status would be 'insufficient' because the syntax of dictionary comprehensions is never explicitly explained in the other snippets.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate list lacks any general explanation or syntax guide for dictionary comprehensions. While an identical question is present, a student wouldn't understand 'why' C is correct or how to construct a comprehension from scratch.", + "missing_concepts": [ + "Dictionary Comprehension Syntax {k: v for ...}", + "The role of len() inside a comprehension" + ], + "proposed_fix": "Add a dedicated 'Key Point' snippet for Dictionary Comprehensions showing the general syntax and a simple example." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Dictionary Comprehensions. Content: You can create dictionaries quickly using the syntax: {key: value for item in list}. For example, {word: len(word) for word in words} creates a mapping from each word to its length.", + "why_helpful": "Provides the missing syntax rule that bridges the gap between 'knowing what we want' and 'writing the code'.", + "why_maybe_unnecessary": "The identical past exam question already provides the answer directly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:09:04Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q08", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q08", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You are given two lists, called students and grades:\n- The students list contains strings representing the names of students.\n- The grades list contains integers representing the students' corresponding grade levels.\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level. That is, the keys of the dictionary are the grade levels and the values are the number of students in that grade.\n\nFor example, if you have:\nstudents = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]\n\nthen the created dictionary grade_counts should be:\n{9: 3, 10: 2, 11: 1}\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "grade_counts = {}\nfor grade in grades:\n if grade not in grade_counts:\n grade_counts[grade] = 0\n grade_counts[grade] += 1", + "b": "grade_counts = {}\nfor student, grade in zip(students, grades):\n if grade in grade_counts:\n grade_counts[grade].append(student)\n else:\n grade_counts[grade] = [student]", + "c": "Both of the given options will work as intended.", + "d": "None of the given options will work as intended." + }, + "correct": "a", + "explanation": "A counts how many times each grade appears, which matches the requested dictionary. B stores lists of students per grade, so it does not produce counts.", + "code_context": "students = ['A', 'B', 'C', 'D', 'E', 'F']\ngrades = [9, 10, 9, 11, 10, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "After excluding the near-identical match, this snippet provides the best example of the logic required: iterating through a list to build a dictionary by checking/setting keys and values." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "After excluding the near-identical match, this snippet provides the best example of the logic required: iterating through a list to build a dictionary by checking/setting keys and values." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates creating a dictionary from two parallel lists (names and ages), which is structurally similar to the students and grades lists in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This piece contains the exact same question, variable names (students, grades), and expected output as the target question." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "After excluding the near-identical match, this snippet provides the best example of the logic required: iterating through a list to build a dictionary by checking/setting keys and values.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates creating a dictionary from two parallel lists (names and ages), which is structurally similar to the students and grades lists in the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The near-identical snippet provides the exact answer. Even without it, the supporting snippets demonstrate dictionary creation from lists and the logic of mapping keys to values.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover the exact question and similar dictionary-building patterns.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:09:14Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q09", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q09", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Dictionaries and Mappings", + "question": "You have a dictionary that represents the scores of students in a math competition:\nmath_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?", + "options": { + "a": "average_score = sum(math_scores.values()) / len(math_scores)\nfor student in math_scores.keys():\n if math_scores[student] > average_score:\n print(student)", + "b": "for student in math_scores:\n if math_scores[student] > (sum(math_scores.values()) / len(math_scores)):\n print(student)", + "c": "Both code segments will work as intended.", + "d": "None of the code segments will work as intended." + }, + "correct": "c", + "explanation": "Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the correct result.", + "code_context": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it lacks the solution code, it presents a near-identical problem structure (employee ratings vs student scores) and the goal of filtering a dictionary by value." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it lacks the solution code, it presents a near-identical problem structure (employee ratings vs student scores) and the goal of filtering a dictionary by value." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Introduces the concept of calculating an 'average' from dictionary data, which is central to the question." + }, + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Shows a relationship between a list of items and a dictionary of counts/values, helping understand how dictionaries track attributes." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "Matches the exact question text, the student score dictionary, and the goal of finding names above the average." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it lacks the solution code, it presents a near-identical problem structure (employee ratings vs student scores) and the goal of filtering a dictionary by value.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Introduces the concept of calculating an 'average' from dictionary data, which is central to the question.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "Shows a relationship between a list of items and a dictionary of counts/values, helping understand how dictionaries track attributes.", + "critical_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "If the near-identical piece is excluded, the remaining snippets describe similar problems but do not explicitly show the syntax for 'sum(dict.values())' or 'len(dict)'. A student might guess based on the problem descriptions, but the technical logic for why both 'math_scores.keys()' and 'math_scores' work as iterators is missing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets are mostly question prompts without the actual code solutions, making it hard to learn syntax.", + "missing_concepts": [ + "sum() and len() applied to dictionary values", + "Equivalence of iterating over a dictionary directly vs. its .keys() method", + "Dictionary filtering syntax" + ], + "proposed_fix": "Add a conceptual snippet explaining common dictionary methods like .keys(), .values(), and how to calculate statistics like averages from them." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Statistics' guide snippet showing: 1. `avg = sum(d.values()) / len(d)`, 2. The fact that `for k in d:` and `for k in d.keys():` are the same.", + "why_helpful": "It directly provides the underlying logic needed to evaluate the options in the question without just giving the answer to a specific exam problem.", + "why_maybe_unnecessary": "The 'extra_practice-4' piece already contains the answer, though using it might be considered 'cheating' the evaluation of general knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:09:41Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q10", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q10", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "String Methods", + "question": "What is the output of the following code segment?\n\nx = 'Hello, World!'\nprint([char for char in x if char.islower()])", + "options": { + "a": "['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd']", + "b": "['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!']", + "c": "['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd']", + "d": "['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd']" + }, + "correct": "a", + "explanation": "The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower().", + "code_context": "x = 'Hello, World!'\nprint([char for char in x if char.islower()])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-1", + "rationale": "This family contains conceptual references to string methods (capitalize) and higher-order patterns (applying transformations to iterables), which are the closest conceptual matches to list comprehensions and method calls, even though the specific syntax is missing." + }, + "top_three_snippets": [ + { + "item_id": "aiq-1", + "rationale": "This family contains conceptual references to string methods (capitalize) and higher-order patterns (applying transformations to iterables), which are the closest conceptual matches to list comprehensions and method calls, even though the specific syntax is missing." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows a string being converted to a list (list(alphabet...)), which helps the student understand that the output of the question's code might be a list of characters." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Identifies 'abc' as a string (str), which confirms the data type of the input variable 'x'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-1", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-1", + "rationale": "This family contains conceptual references to string methods (capitalize) and higher-order patterns (applying transformations to iterables), which are the closest conceptual matches to list comprehensions and method calls, even though the specific syntax is missing.", + "critical_piece_ids": [ + "aiq-1" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Shows a string being converted to a list (list(alphabet...)), which helps the student understand that the output of the question's code might be a list of characters.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "Identifies 'abc' as a string (str), which confirms the data type of the input variable 'x'.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-1", + "rationale": "", + "needed_piece_ids": [ + "aiq-1" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets fail to explain the syntax of list comprehensions ([item for item in iterable if condition]) or the functionality of the .islower() method. A student without prior knowledge would not know what 'islower' filters for (letters vs punctuation/spaces) or how the loop-within-brackets structure works.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gaps are the list comprehension syntax and the definition of boolean string methods like .islower().", + "missing_concepts": [ + "List Comprehensions", + ".islower() string method", + "Filtering logic in comprehensions" + ], + "proposed_fix": "Add a snippet specifically explaining list comprehensions with filtering, and another covering common string validation methods (.islower, .isupper, .isdigit, .isalpha)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: List Comprehensions. Content: A concise way to create lists. Syntax: [expression for item in iterable if condition]. Example: [c for c in 'Abc!' if c.islower()] results in ['b', 'c'].", + "why_helpful": "Directly explains the syntax used in the question, enabling the student to parse the code.", + "why_maybe_unnecessary": "If the student already understands loops and if-statements, they might guess the behavior, but it's risky.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Case Methods. Content: .islower() returns True if all cased characters in the string are lowercase and there is at least one cased character. .isupper() returns True for uppercase. Non-cased characters (numbers, spaces, punctuation) return False for these checks.", + "why_helpful": "Explains exactly what the filter in the question does, preventing confusion about whether ',' or ' ' are included.", + "why_maybe_unnecessary": "The name 'islower' is somewhat self-explanatory, but the behavior with punctuation is a common pitfall.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:10:07Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:aiq-1", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Fundamentals", + "subtopic_title": "", + "search_text": "Given s1 = 'abcd', which code fragment correctly updates s1 to 'Abcd'?\nStrings are immutable. s1.capitalize() returns a new string, so you must assign that result back to the name s1.\nString Methods" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Condition flow and branch result\nExam • midterm_2024 • Q1\nConsider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • trial_midterm • Q17\nA def square" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Generators and Iterators", + "subtopic_title": "", + "search_text": "What is the primary advantage of a generator over a list for large datasets?\nGenerators do not store the entire sequence in memory, which is essential for very large or infinite datasets.\nGenerators" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types.\nI is correct (e.g. a=1, b=2, both int). II is incorrect — if two objects have the same value " + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Operators and Truth", + "subtopic_title": "", + "search_text": "What is the result of (a//b)*b + a%b?\nArithmetic operators" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q11", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q11", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Functions and Imports", + "question": "What will be the output of the following code segment?\n\nlist1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)", + "options": { + "a": "[1, 2, 3, 4]", + "b": "[2, 2, 2, 2]", + "c": "[6, 12, 18, 24]", + "d": "[2.5, 2.5, 2.5, 2.5]" + }, + "correct": "b", + "explanation": "The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2.", + "code_context": "list1 = [5, 10, 15, 20]\nlist2 = [2, 4, 6, 8]\nresult = []\n\nfor a, b in zip(list1, list2):\n result.append(a // b)\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "This snippet is the only one showing `list.append()`, which is used in the question to build the results list." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "This snippet is the only one showing `list.append()`, which is used in the question to build the results list." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains that `print` is a built-in function used to output arguments to the screen." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "This snippet is the only one showing `list.append()`, which is used in the question to build the results list.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Explains that `print` is a built-in function used to output arguments to the screen.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the `zip()` function or the floor division operator (`//`). A student with zero knowledge would not know how to combine the lists or what calculation is being performed.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Critical missing explanations for the zip() built-in and the floor division operator.", + "missing_concepts": [ + "zip() function mechanics", + "floor division operator (//)", + "iteration over zipped pairs" + ], + "proposed_fix": "Add a key point or AI example explaining how zip(a, b) pairs elements and how // returns the integer quotient (rounding down)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a Key Point for Week 1: 'The `//` operator performs floor division, which divides two numbers and rounds the result down to the nearest whole integer (e.g., `5 // 2` is `2`).'", + "why_helpful": "Essential for determining the values in the resulting list (distinguishing between option b and d).", + "why_maybe_unnecessary": "Basic arithmetic is often assumed, but floor division is specific to Python's syntax.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add an AI Example or Key Point for Week 2: 'The `zip(list1, list2)` function combines two lists into a sequence of pairs. In a loop `for a, b in zip(...)`, `a` takes values from the first list and `b` takes values from the second list simultaneously.'", + "why_helpful": "The student cannot process the loop logic without understanding how zip handles multiple lists.", + "why_maybe_unnecessary": "None.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:10:26Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
              • A function is a grouping of code that can perform a certain task and can be re-used \n
              • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Which script does NOT print the correct answer for the area of a circle?\nA\nB\nC\nD\nC\nIf math is imported as constants, it must be referred to as 'constants.pi'. 'math.pi' will no longer be available unless 'math' was also imported directly." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ai-example-8", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95" + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller." + }, + { + "item_id": "ai-example-3", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "from-import binds only the imported name\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `im" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually availabl" + }, + { + "item_id": "kp-1", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import r" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-16-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-16-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather alert system." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q12", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q12", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Sequences and Access", + "question": "Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10].\nWhich of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]?", + "options": { + "a": "subset = numbers[::-2][::-1]", + "b": "subset = numbers[-1::-2]", + "c": "subset = numbers[::-1][::2]", + "d": "subset = numbers[::-2]" + }, + "correct": "a", + "explanation": "A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2].", + "code_context": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Aside from the identical exam piece, this is the only other snippet that deals with transforming and reversing lists (using sorting), although it lacks the specific slicing syntax ([start:stop:step]) required for this question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Aside from the identical exam piece, this is the only other snippet that deals with transforming and reversing lists (using sorting), although it lacks the specific slicing syntax ([start:stop:step]) required for this question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "rationale": "This is the exact same question, including the same list values and the specific list being created, although the mapping of letters (a, b, c, d) to the specific code lines in the explanation may differ slightly." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Aside from the identical exam piece, this is the only other snippet that deals with transforming and reversing lists (using sorting), although it lacks the specific slicing syntax ([start:stop:step]) required for this question.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-6-w1-sequences-and-access" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "If the near-identical past exam piece is excluded, there are no snippets in the current candidate set that explain the fundamentals of Python slicing syntax ([start:stop:step]). A student without prior knowledge would not be able to deduce the behavior of negative steps or chained slices from the remaining snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The repository is missing foundational material on sequence slicing, which is a core concept for the 'Sequences and Access' topic.", + "missing_concepts": [ + "Slicing syntax [start:stop:step]", + "Negative step behavior in slices (reversing)", + "Chained slicing behavior" + ], + "proposed_fix": "Add a concept-based snippet (not an exam question) that explicitly explains how [::1], [::-1], [::2], and [start::step] work with examples using a simple list." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet family titled 'Slicing Fundamentals' under the 'Sequences and Access' topic. Include a piece that explains the [start:stop:step] syntax, specifically highlighting that a step of -1 reverses the sequence and a step of -2 takes every second element in reverse.", + "why_helpful": "This would allow students to solve slicing problems logically rather than relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "If the goal is only to provide exam-identical practice, the existing identical snippet is sufficient, but it doesn't support 'almost zero prior knowledge' for variations of the question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:11:16Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Corre" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q13", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q13", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "string - find - 3", + "question": "You have a string variable called sentence:\nsentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'\n\nYou want to replace only the second occurrence of \"book\" with \"novel\" in the sentence and save this as new_sentence.\n\nSo:\nprint(new_sentence)\nshould print:\nI bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book.\n\nWhich of the following code segments will work as intended?\n\nHint:\nThe string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively.", + "options": { + "a": "index = sentence.find('book')\nindex = sentence.find('book', index + 1)\nnew_sentence = sentence[:index] + 'novel' + sentence[index + 4:]", + "b": "new_sentence = sentence.replace(\"book\", \"novel\", 2)\nnew_sentence = new_sentence.replace(\"novel\", \"book\", 1)", + "c": "Both options will work as intended.", + "d": "None of the options will work as intended." + }, + "correct": "c", + "explanation": "Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of \"book\" with \"novel\" and then changes only the first replaced occurrence back to \"book\", so only the second occurrence remains replaced.", + "code_context": "sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves extracting specific substrings (TLDs) from a string (URL), which conceptually aligns with the string manipulation and positioning logic required for this question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves extracting specific substrings (TLDs) from a string (URL), which conceptually aligns with the string manipulation and positioning logic required for this question." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Shows string slicing syntax (e.g., alphabet[1::2]), which is necessary to understand Option A's use of indices to reconstruct the sentence." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves extracting specific substrings (TLDs) from a string (URL), which conceptually aligns with the string manipulation and positioning logic required for this question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Shows string slicing syntax (e.g., alphabet[1::2]), which is necessary to understand Option A's use of indices to reconstruct the sentence.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The candidate snippets do not explain the `replace()` method's third argument (count), which is central to Option B. While the question provides a hint for `find()`, none of the snippets demonstrate the string concatenation pattern `s[:i] + 'new' + s[i+len:]` used in Option A.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing core documentation for string methods 'replace' and practical string reconstruction using slicing.", + "missing_concepts": [ + "string.replace(old, new, count) behavior", + "String reconstruction via slicing and concatenation", + "Practical usage of find() with the start index parameter" + ], + "proposed_fix": "Add a snippet covering common string methods (find, replace, count) and an example of 'surgical' string editing using slicing." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'String Methods Reference' piece. It should explain: 1. text.find(sub, start) finds the next occurrence after a specific index. 2. text.replace(old, new, maxreplace) limits how many occurrences are changed. 3. How slicing text[:index] + replacement + text[index+len:] works to swap characters at a known position.", + "why_helpful": "Directly addresses both Option A (slicing/concatenation) and Option B (replace count/reverting) logic.", + "why_maybe_unnecessary": "The question includes a hint for find(), but it is insufficient for the replace/slicing logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:11:38Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q14", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q14", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "string - fstring - 3", + "question": "You have the following objects loaded in Python:\nfruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3\n\nYou want to print the following sentence:\nI have 3 fruits: apple, banana, and orange.\n\nWhich of the following code fragments will achieve the desired output?", + "options": { + "a": "message = f\"I have {count} fruits: {', '.join(fruits)}.\"\nprint(message)", + "b": "message = f\"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}.\"\nprint(message)", + "c": "Both code fragments will achieve the desired output.", + "d": "Neither of the code fragments will achieve the desired output." + }, + "correct": "b", + "explanation": "Option B matches the required sentence exactly, including the word \"and\" before the final fruit. Option A joins the list without \"and\", so it does not produce the exact requested output.", + "code_context": "fruits = [\"apple\", \"banana\", \"orange\"]\ncount = 3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves formatting a string using list/dictionary data to produce a specific sentence pattern, which is the exact task in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves formatting a string using list/dictionary data to produce a specific sentence pattern, which is the exact task in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Discusses writing a function to format strings (phone numbers), which relates to the concept of string manipulation and output structure." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Mentions list manipulation, though it focuses more on slicing than simple indexing." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This snippet involves formatting a string using list/dictionary data to produce a specific sentence pattern, which is the exact task in the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Discusses writing a function to format strings (phone numbers), which relates to the concept of string manipulation and output structure.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "Mentions list manipulation, though it focuses more on slicing than simple indexing.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain f-string syntax (f\"...\"), list indexing (how to access 'apple' via fruits[0]), or the .join() method. A student without prior knowledge would not understand the syntax used in the options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets focus on high-level exam questions rather than the foundational syntax required (f-strings and indexing).", + "missing_concepts": [ + "f-string syntax and variable interpolation", + "List indexing (0-based access)", + "String .join() method functionality" + ], + "proposed_fix": "Add a foundational snippet explaining how f-strings work and how to access specific elements in a list using square brackets." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Formatting and List Access. Content: Use f-strings like f'Text {variable}' to insert values into strings. To access items in a list, use index numbers starting at 0: list[0] is the first item, list[1] the second, etc.", + "why_helpful": "This directly explains both the f-string syntax and the indexing syntax used in Option B.", + "why_maybe_unnecessary": "If the student already understands basic Python syntax, but the prompt assumes 'almost zero prior knowledge'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:12:04Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q15", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q15", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "string - operations - 3", + "question": "A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the \"@\" symbol and a domain name, which comes after the \"@\" symbol.\n\nYou need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments.\n\nFor example, if you execute the following command:\nprint(main('example@example.com', 'student@uva.nl', 'email@address.com'))\n\nthe output should be:\n local domain\n0 example example.com\n1 student uva.nl\n2 email address.com\n\nWhich of the following code segments will return this dataframe as intended?\n\nYou may assume that pandas is already imported as pd.", + "options": { + "a": "def main(*args):\n data = {}\n data['local'] = pd.Series([email.split(\"@\")[0] for email in args])\n data['domain'] = pd.Series([email.split(\"@\")[1] for email in args])\n return pd.DataFrame(data)", + "b": "def main(args):\n return pd.DataFrame({\n 'local': [email.split(\"@\")[1] for email in args],\n 'data': [email.split(\"@\")[0] for email in args]})", + "c": "def main(*args):\n data = {}\n for email in args:\n data['local'] = email.split(\"@\")[0]\n data['domain'] = email.split(\"@\")[1]\n return pd.DataFrame(data)", + "d": "def main(*args):\n local = []\n domain = []\n for email in args:\n local.append(email.split(\"@\")[0])\n domain.append(email.split(\"@\")[1])\n return pd.DataFrame({local: domain for local, domain in zip(local, domain)})" + }, + "correct": "a", + "explanation": "Option A builds aligned pandas Series for the local parts and domains, then returns them in a DataFrame with the correct column names. The other options either swap fields, overwrite values, or construct the DataFrame incorrectly.", + "code_context": "print(main('example@example.com', 'student@uva.nl', 'email@address.com'))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet directly addresses the requirement for a function that accepts a 'flexible number of arguments' (*args), which is a key differentiator between the correct and incorrect options." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet directly addresses the requirement for a function that accepts a 'flexible number of arguments' (*args), which is a key differentiator between the correct and incorrect options." + }, + { + "item_id": "aiq-4", + "rationale": "Shows the implementation syntax for iterating over *args ('for num in args'), which is necessary for extracting data from each email string." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides context for pandas Series, which are explicitly used in the correct option (Option A) to build the DataFrame." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers the *args requirement." + }, + { + "item_id": "aiq-4", + "rationale": "Provides the loop syntax for flexible arguments." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Validates the use of pd.Series." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides a conceptual parallel for extracting parts of a string (TLD from URL) even if the delimiter differs." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet directly addresses the requirement for a function that accepts a 'flexible number of arguments' (*args), which is a key differentiator between the correct and incorrect options.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "Shows the implementation syntax for iterating over *args ('for num in args'), which is necessary for extracting data from each email string.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides context for pandas Series, which are explicitly used in the correct option (Option A) to build the DataFrame.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "Covers the *args requirement.", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Provides the loop syntax for flexible arguments.", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Validates the use of pd.Series.", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides a conceptual parallel for extracting parts of a string (TLD from URL) even if the delimiter differs.", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover the flexible arguments (*args) and the looping mechanics, and provide context for pandas Series. However, the specific syntax for constructing a DataFrame from a dictionary of Series is not explicitly demonstrated, nor is the use of '.split()' on strings for character-based extraction.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The student would know how to handle multiple arguments and loops, but might struggle with the specific string extraction (.split) and DataFrame assembly syntax.", + "missing_concepts": [ + "string.split() method", + "pd.DataFrame(dictionary) construction", + "List comprehension for Series creation" + ], + "proposed_fix": "Add a snippet or detail piece showing how to create a DataFrame from a dictionary of lists or Series, and another showing string splitting." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet showing: 'df = pd.DataFrame({\"col1\": [values], \"col2\": [values]})' or building a DF from pd.Series objects.", + "why_helpful": "The question relies on knowing that passing a dictionary to pd.DataFrame() creates columns from keys.", + "why_maybe_unnecessary": "Students might infer DataFrame structure from previous exercises, but it's a specific API detail.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:12:27Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q16", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q16", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Easy_1", + "question": "You have the following definition of a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nWhat will be the output if we execute the following lines of code?\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')", + "options": { + "a": "True\nTrue", + "b": "True\nFalse", + "c": "False\nTrue", + "d": "False\nFalse" + }, + "correct": "a", + "explanation": "The name comparison is true because the object stores 'John Smith', and the gender comparison is also true because the default value 'not specified' is used when no gender is provided.", + "code_context": "class Employee:\n def __init__(self, name, role, gender = 'not specified'):\n self.name = name\n self.role = role\n self.gender = gender\n\nemployee1 = Employee('John Smith', 'HR representative')\nprint(employee1.name == 'John Smith')\nprint(employee1.gender == 'not specified')" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "This snippet is the most relevant because it explicitly explains how default arguments work (e.g., 'y defaults to 11' when omitted), which is the key 'trick' for the gender attribute in this question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "This snippet is the most relevant because it explicitly explains how default arguments work (e.g., 'y defaults to 11' when omitted), which is the key 'trick' for the gender attribute in this question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the conceptual framework for defining classes and initializing attributes (name, mode) during object construction." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Demonstrates that comparison operations (==) in Python print 'True' or 'False', helping a zero-knowledge student understand the output format." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "This snippet is the most relevant because it explicitly explains how default arguments work (e.g., 'y defaults to 11' when omitted), which is the key 'trick' for the gender attribute in this question.", + "critical_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the conceptual framework for defining classes and initializing attributes (name, mode) during object construction.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Demonstrates that comparison operations (==) in Python print 'True' or 'False', helping a zero-knowledge student understand the output format.", + "critical_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain default arguments and show that comparisons result in True/False. However, there is no direct example showing 'self.attribute = parameter' being accessed later via 'object.attribute', though it is somewhat inferable from the OOP Fundamentals piece.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing a concrete code example of attribute assignment and retrieval in a class.", + "missing_concepts": [ + "Explicit syntax for attribute access (obj.attr)", + "Mapping of __init__ arguments to self-assigned attributes" + ], + "proposed_fix": "Add a snippet showing a simple class 'Person' where 'self.name = name' is followed by a 'print(p1.name == ...)' example." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet: 'class SimpleObj: def __init__(self, val): self.val = val; o = SimpleObj(10); print(o.val == 10) # Prints True'.", + "why_helpful": "It directly bridges the gap between the constructor logic and the print statement outcome.", + "why_maybe_unnecessary": "The logic is arguably the most fundamental part of OOP taught in week 4, but for a student with zero knowledge, seeing the '==' result is safer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:12:48Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q17", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q17", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_2", + "question": "Which other code fragment will print the same output as the following?\n\nfrom datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)", + "options": { + "a": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days)", + "b": "from datetime import datetime, timedelta\nprint(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1)", + "c": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days)", + "d": "from datetime import datetime, timedelta\nprint((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days)" + }, + "correct": "d", + "explanation": "The original code computes the difference in days between January 10 and January 1, then adds 1, yielding 10. Option D also yields 10 by subtracting January 1 from January 11.", + "code_context": "from datetime import datetime, timedelta\nprint((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This piece explains the exact mechanics required: that subtracting two datetime objects results in a timedelta, that .days converts it to an integer, and it even mentions the '+ 1' logic for inclusive counting." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This piece explains the exact mechanics required: that subtracting two datetime objects results in a timedelta, that .days converts it to an integer, and it even mentions the '+ 1' logic for inclusive counting." + }, + { + "item_id": "kp-8", + "rationale": "Contains key point kp-8 which acknowledges the 'Which code fragment prints the SAME output as...?' question pattern frequently seen in exams." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This piece explains the exact mechanics required: that subtracting two datetime objects results in a timedelta, that .days converts it to an integer, and it even mentions the '+ 1' logic for inclusive counting.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "rationale": "Contains key point kp-8 which acknowledges the 'Which code fragment prints the SAME output as...?' question pattern frequently seen in exams.", + "critical_piece_ids": [ + "kp-8" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The best snippet covers the subtraction logic and attribute access perfectly. However, there is no explanation for datetime.strptime() or the standard datetime(Y, M, D) constructor. A student would have to infer that '2023/1/10' in strptime is equivalent to datetime(2023, 1, 10), which is a reasonable but unverified leap for a total beginner.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Lack of documentation for datetime object creation methods (constructor vs parsing).", + "missing_concepts": [ + "datetime.strptime()", + "datetime(year, month, day) constructor" + ], + "proposed_fix": "Add an AI example or key point showing that datetime objects can be created via numeric arguments or by parsing strings with strptime." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a Datetime Creation snippet: 'datetime(2023, 1, 10) creates a date object for Jan 10. datetime.strptime(\"2023/1/10\", \"%Y/%m/%d\") parses a string into the same object.'", + "why_helpful": "Directly links the syntax used in the question's code to the syntax used in the options.", + "why_maybe_unnecessary": "The date values are identical, so students might assume equivalence without knowing the syntax.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:13:17Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "kp-8", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Which code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others." + }, + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Basic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step g" + }, + { + "item_id": "ai-example-7", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Negative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: star" + }, + { + "item_id": "kp-6", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Syntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "List is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]\nImmutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the sam" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Objects and Names", + "subtopic_title": "Objects, Types, Mutability, Assignment, and Names", + "search_text": "Two names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True\nAssignment binds the left-hand name to the object produced on the right-hand side." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-3-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-midterm_2023-3-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Which other program will give the same output as the following code snippet?" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-22-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2024-22-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?\nA z = [[\"a\", \"b\", \"c\"], [1, 2, 3, 4]]\nprint(z[0][1] + str(z[1][3])*3)\nB print('b'+ str(8 % 4)*3)\nC print('b' + str(" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-5-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-midterm_2024-5-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Which other program will produce the same output as the following code snippet?" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-5-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 !" + } + ] + }, + { + "snippet_id": "item:ks-df3b849d59", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "ks-df3b849d59", + "item_type": "source_lecture", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Exam question types\nWhich code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others. / Which correctly solves the problem? Option" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-extra_practice-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modif" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q18", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q18", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "pandas - easy - 3", + "question": "Suppose you have the following DataFrame called df:\n Player Age Height\n0 John 25 180\n1 Jane 30 165\n2 Alex 27 175\n\nYou may assume that pandas is already imported as pd.\n\nWhich of the following lines of code will give an error?", + "options": { + "a": "print(df.loc[:, 'Age'])", + "b": "print(df.loc[df['Height'] > 170, ['Player', 'Age']])", + "c": "print(df[['Player', 'Age']])", + "d": "print(df[1, 'Age'])" + }, + "correct": "d", + "explanation": "Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing does not accept the tuple (1, 'Age') in this form.", + "code_context": "df = pd.DataFrame({\n 'Player': ['John', 'Jane', 'Alex'],\n 'Age': [25, 30, 27],\n 'Height': [180, 165, 175]\n})" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the most relevant as it explicitly covers 'Inspecting and Selecting Data' in Pandas, though the provided text is minimal." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the most relevant as it explicitly covers 'Inspecting and Selecting Data' in Pandas, though the provided text is minimal." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides context for standard column selection in Pandas (df['A']), which helps rule out simple bracket indexing for multiple axes." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the most relevant as it explicitly covers 'Inspecting and Selecting Data' in Pandas, though the provided text is minimal.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Provides context for standard column selection in Pandas (df['A']), which helps rule out simple bracket indexing for multiple axes.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets do not explicitly show the difference between .loc indexing and standard bracket indexing. A student wouldn't know that df[row, col] is invalid while df.loc[row, col] is valid based on these snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no information explaining the specific syntax rules for Pandas DataFrame indexing, specifically why tuples are not allowed in standard brackets.", + "missing_concepts": [ + "Pandas .loc vs [] indexing syntax", + "Multi-axis indexing rules in DataFrames" + ], + "proposed_fix": "Add a snippet or exam question that explicitly demonstrates that df[1, 'col'] raises a KeyError or TypeError, whereas df.loc[1, 'col'] works." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet explaining that df[label] or df[[list]] selects columns, but df[row_label, col_label] is invalid. Contrast this with df.loc[row_label, col_label] which is the correct way to select both dimensions.", + "why_helpful": "This directly explains why option D is the 'error' and why options A and B are valid.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:13:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q19", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q19", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Function_1", + "question": "You have the following definition for a class called Animals:\n\nclass Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\n # missing lines\n # ...\n\nYou need to add two methods to the class:\n1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'.\n2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'.\n\nFor example, if we execute the following commands:\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())\n\nthe output should be:\nMeow!\nCannot swim!\nBlob!\nCannot walk!\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def walk(self):\n return self.sound if self.legs else 'Cannot walk!'\ndef swim(self):\n return self.sound if self.fin else 'Cannot swim!'", + "b": "def walk(self):\n if self.legs == True:\n return self.sound\n else:\n return 'Cannot walk!'\ndef swim(self):\n if self.fin == True:\n return self.sound\n else:\n return 'Cannot swim!'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "c", + "explanation": "Both shown method implementations use the instance attributes to return the animal's sound when the relevant boolean attribute is present and the required fallback message otherwise.", + "code_context": "class Animals:\n def __init__(self, name, sound, legs=None, fin=None):\n self.name = name\n self.sound = sound\n self.legs = legs\n self.fin = fin\n\ncat = Animals('kitty', legs=True, sound='Meow!')\nfish = Animals('nemo', fin=True, sound='Blob!')\nprint(cat.walk())\nprint(cat.swim())\nprint(fish.swim())\nprint(fish.walk())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly describes adding a method ('compare') to an existing class that uses instance attributes to return a result based on conditional logic, which mirrors the task of adding the 'walk' and 'swim' methods." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly describes adding a method ('compare') to an existing class that uses instance attributes to return a result based on conditional logic, which mirrors the task of adding the 'walk' and 'swim' methods." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational context for defining a class with multiple attributes and how they are initialized in the constructor (__init__), helping the student understand 'self.legs' and 'self.fin'." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Demonstrates basic if/else control flow for decision-making, which is the core logic required for option 'b'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly describes adding a method ('compare') to an existing class that uses instance attributes to return a result based on conditional logic, which mirrors the task of adding the 'walk' and 'swim' methods.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational context for defining a class with multiple attributes and how they are initialized in the constructor (__init__), helping the student understand 'self.legs' and 'self.fin'.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Demonstrates basic if/else control flow for decision-making, which is the core logic required for option 'b'.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class structure, method definitions, and basic if/else logic (Option 'b'). However, there is no explanation of the 'ternary operator' (x if condition else y) used in Option 'a'. Without knowing this syntax, a student cannot confidently select 'c' (Both work).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main gap is the lack of documentation for the one-line ternary if-else operator syntax used in option 'a'.", + "missing_concepts": [ + "ternary conditional operator (x if condition else y)" + ], + "proposed_fix": "Add an AI-generated snippet or a common question item that explains the 'Inline If-Else' or 'Ternary Operator' syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Inline If-Else (Ternary Operator)\nContent: You can write a simple if-else on one line using the syntax: [value_if_true] if [condition] else [value_if_false]. \nExample: 'Meow!' if self.legs else 'Cannot walk!'", + "why_helpful": "This allows students to recognize that option 'a' in the exam question is valid Python syntax, enabling them to correctly choose 'c'.", + "why_maybe_unnecessary": "Option 'b' is standard if-else, so they might guess Option 'a' is just a shorthand if they are intuitive, but explicit documentation is safer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:14:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q20", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q20", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "6_OOP_Hard_3", + "question": "You have the following definition for a class named Movie.\n\nclass Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\n # missing lines\n # ...\n\nYou need to add three methods to the class:\n1. The add_review() method, which adds review scores to the 'reviews' attribute.\n2. The rating() method, which computes and returns the average review score of all scores stored in the 'reviews' attribute. If there are no reviews, the method should return 0.\n3. The compare() method, which compares the average review scores of two Movie objects and returns the title of the Movie object with the higher average review score, i.e., the name of the movie you should watch. In case both Movie objects have the same average review score, the method should return 'Either'.\n\nFor example, if we execute the following commands:\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))\n\nthe output should be:\nIn Bruges\n\nWhich of the following code segments should you place on the missing lines in the class definition to achieve what you want?", + "options": { + "a": "def add_review(self, score):\n self.reviews += score\ndef rating(self):\n return sum(self.reviews)/len(self.reviews) if self.reviews else 0\ndef compare(self, other):\n for first, second in [(self, other), (other, self)]:\n return first.title if first.rating() > second.rating() else 'Either'", + "b": "def add_review(score):\n reviews.append(score)\ndef rating():\n if reviews:\n return sum(reviews)/len(reviews)\n else:\n return 0\ndef compare(self, other):\n if self.rating > other.rating:\n return self.title\n elif self.rating < other.rating:\n return other.title\n else:\n return 'Either'", + "c": "Both code segments will work as intended.", + "d": "Neither code segment will work as intended." + }, + "correct": "d", + "explanation": "The first code segment is broken because it tries to add an integer directly to a list and its compare logic cannot return the other movie's title correctly. The second code segment omits self where needed and compares method objects instead of method results.", + "code_context": "class Movie:\n def __init__(self, title, director, reviews = None):\n self.title = title\n self.director = director\n self.reviews = reviews if reviews else []\n\nmovie1 = Movie('In Bruges', 'Martin McDonagh', [5, 3, 5, 4])\nmovie2 = Movie('Parasite', 'Bong Joon Ho')\nprint(movie1.compare(movie2))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "This family provides comprehensive technical guidance on instance methods, specifically: using 'self' in definitions, using '.append()' for list state updates, and structuring comparison logic between two objects." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "This family provides comprehensive technical guidance on instance methods, specifically: using 'self' in definitions, using '.append()' for list state updates, and structuring comparison logic between two objects." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Provides a standard reference for class initialization and attribute assignment, helping students recognize the basic structure expected in the question's class." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Describes a nearly identical scenario: a 'compare' method for a class (Book) that evaluates average review scores to recommend one instance over another." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "This family provides comprehensive technical guidance on instance methods, specifically: using 'self' in definitions, using '.append()' for list state updates, and structuring comparison logic between two objects.", + "critical_piece_ids": [ + "manual-oop-state-compare", + "ai-example-6", + "manual-oop-compare-none-case" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "Provides a standard reference for class initialization and attribute assignment, helping students recognize the basic structure expected in the question's class.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "", + "needed_piece_ids": [ + "manual-oop-state-compare", + "ai-example-6", + "manual-oop-compare-none-case" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The pieces in the best family explicitly address the three fatal flaws in the question's options: 'manual-oop-state-compare' shows '.append()' (rejecting option a's '+=' list error), 'ai-example-6' clarifies method call syntax vs method objects (rejecting option b's property comparison), and both reinforce the mandatory use of 'self' in method signatures.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide excellent coverage of the specific syntax and logic pitfalls tested in this question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:14:49Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-oop-compare-none-case", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Return `None` when neither object clearly wins\nclass Book:\n def __init__(self, title, scores):\n self.title = title\n self.scores = scores\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def winner_against(self, other):\n if se" + }, + { + "item_id": "manual-oop-state-compare", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.sc" + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`." + }, + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` is passed automatically in method calls\nclass Clock:\n def set_hour(self, hour):\n self.hour = hour\n\nc = Clock()\nc.set_hour(9)\n# c.set_hour(c, 9) # wrong: passes one argument too many\nWriting `obj.method(x)` already passes `self` for you. Inside the method, store " + }, + { + "item_id": "manual-oop-init-defaults", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q21", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q21", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_1", + "question": "You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY.\n\nThe function should return a list containing 10 strings representing dates, all in that same format.\nThe first element of the list should be the original input date.\nEach further element of the list should be a string representing the date that is exactly one week after the preceding element of the list.\n\nTake a look at the following code segment:\n\nfrom datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list\n\nWill this code segment work as intended? If not, then why not?", + "options": { + "a": "The code will not work because the two methods strptime() and strftime() are mixed up.", + "b": "This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings.", + "c": "This code will not work as intended, because there will be 11 strings in the list instead of 10.", + "d": "This code segment will work as intended." + }, + "correct": "b", + "explanation": "After the first append inside the loop, the list contains formatted date strings. On the next iteration the code tries to add a timedelta to that string, which is not allowed.", + "code_context": "from datetime import datetime, timedelta\n\ndef main(string):\n date = datetime.strptime(string, '%d-%m-%Y')\n str_list = [date]\n for i in range(1, 10):\n str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y'))\n return str_list" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "It contains general debugging advice to trace returned values and observe list state after each call, which is the key to spotting that the list elements change from datetime objects to strings." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "It contains general debugging advice to trace returned values and observe list state after each call, which is the key to spotting that the list elements change from datetime objects to strings." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "It contains general debugging advice to trace returned values and observe list state after each call, which is the key to spotting that the list elements change from datetime objects to strings.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the 'datetime' module, the difference between 'strptime' and 'strftime', or the fact that 'timedelta' objects cannot be added to strings. Without this domain knowledge, a student with zero Python experience cannot distinguish between options (a) and (b).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing core documentation for the datetime library and type-safety rules for datetime arithmetic.", + "missing_concepts": [ + "datetime.strptime vs datetime.strftime", + "timedelta arithmetic (cannot add to strings)", + "datetime object vs formatted string" + ], + "proposed_fix": "Add a dedicated 'Datetime' snippet family covering strptime, strftime, and timedelta usage." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet for 'Week 8: Datetime' explaining: 1. datetime.strptime(str, fmt) creates an object. 2. obj.strftime(fmt) creates a string. 3. timedelta can only be added to datetime objects, not strings.", + "why_helpful": "This provides the missing domain knowledge required to understand why adding a timedelta to a previously-formatted string (item in the list) causes a crash.", + "why_maybe_unnecessary": "If the student already covered this in class, they might remember, but for a 'zero-knowledge' student, it is essential.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:15:12Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q22", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q22", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_3", + "question": "Suppose you have the following DataFrame called df:\n\n Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023\n\nYou need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this:\n\n Day Month Year Date\n0 1 5 2023 01-05-2023\n1 8 5 2023 08-05-2023\n2 15 5 2023 15-05-2023\n3 22 5 2023 22-05-2023\n4 29 5 2023 29-05-2023\n\nWhich of the following code segments will achieve what you want? You may assume that the pandas module is already imported as pd.", + "options": { + "a": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "b": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "c": "from datetime import datetime\ndf['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])])", + "d": "from datetime import datetime\ndf['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])])" + }, + "correct": "a", + "explanation": "Option A builds real datetime objects using year, month, and day in the correct order and then formats each one as DD-MM-YYYY.", + "code_context": "Day Month Year\n0 1 5 2023\n1 8 5 2023\n2 15 5 2023\n3 22 5 2023\n4 29 5 2023" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This snippet involves processing parallel lists (names and ages), which is the standard context in this course for introducing the 'zip' function. This helps a student understand the iteration structure used in the correct answer." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This snippet involves processing parallel lists (names and ages), which is the standard context in this course for introducing the 'zip' function. This helps a student understand the iteration structure used in the correct answer." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates the structural pattern of creating a new DataFrame column ('C') based on values from existing columns ('A' and 'B')." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This snippet involves processing parallel lists (names and ages), which is the standard context in this course for introducing the 'zip' function. This helps a student understand the iteration structure used in the correct answer.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates the structural pattern of creating a new DataFrame column ('C') based on values from existing columns ('A' and 'B').", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets provide information about the 'datetime' module, which is essential for solving this problem. There is no guidance on the 'datetime(year, month, day)' constructor's argument order, the difference between 'strftime' (formatting) and 'strptime' (parsing), or the specific formatting codes (like %d, %m, %Y) required. A student with zero knowledge would be forced to guess between option A and C based on the variable order alone.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide the structural framework for Pandas column creation but completely omit the 'datetime' module logic required to construct the date string.", + "missing_concepts": [ + "datetime.datetime(year, month, day) constructor argument order", + "Usage of .strftime() to format datetime objects into strings", + "Difference between strftime and strptime", + "Date formatting syntax (%d, %m, %Y)" + ], + "proposed_fix": "Add a new snippet covering the basics of the 'datetime' module, specifically showing object construction and the use of strftime for formatting." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Python Datetime Formatting' snippet showing: 1) dt = datetime(year, month, day) and 2) dt.strftime('%d-%m-%Y') to produce '31-12-2023'.", + "why_helpful": "This would allow the student to identify the correct constructor order (Option A vs C) and the correct method for string output (strftime vs strptime).", + "why_maybe_unnecessary": "Only if the student is expected to infer 'strftime' from 'string format' and 'strptime' from 'string parse' without any reference.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:16:07Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q23", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q23", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "pandas - hard - 3", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False.\n- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary.\n- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary.\n\nThat is, the final result printed should be:\n Name Age Salary Above_average Salary_difference\n1 Jane 30 65000 True 100\n2 Alex 35 80000 True 16000\n3 Lisa 40 70000 True 6000\n\nWhich of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd.", + "options": { + "a": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']])\ndf['Salary_difference'] = df['Salary'] - mean_salary\nprint(df[df['Above_average']==True])", + "b": "mean_salary = round(df['Salary'].mean())\ndf['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False)\ndf['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary)\nprint(df[df['Salary_difference']>0])", + "c": "Both blocks of code will work as intended.", + "d": "None of the blocks of code will work as intended." + }, + "correct": "c", + "explanation": "Both code blocks compute the rounded mean salary, derive an above-average indicator, compute salary differences from that mean, and filter the rows with positive differences.", + "code_context": "Name Age Salary\n0 John 25 50000\n1 Jane 30 65000\n2 Alex 35 80000\n3 Lisa 40 70000\n4 Mark 28 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows how to create a new column (C) from existing columns (A and B) using vectorized operations, which directly relates to creating 'Salary_difference' and assigning new columns in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows how to create a new column (C) from existing columns (A and B) using vectorized operations, which directly relates to creating 'Salary_difference' and assigning new columns in the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a boolean mask on the index or columns for filtering rows, which is necessary for understanding the print(df[df[...]]) operations in the options." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes the concept of creating a new Series based on the difference between elements and their mean, supporting the logic in Operation 2." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Teaches column creation and vectorization." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides a hint towards boolean filtering syntax." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows how to create a new column (C) from existing columns (A and B) using vectorized operations, which directly relates to creating 'Salary_difference' and assigning new columns in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions using a boolean mask on the index or columns for filtering rows, which is necessary for understanding the print(df[df[...]]) operations in the options.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes the concept of creating a new Series based on the difference between elements and their mean, supporting the logic in Operation 2.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Teaches column creation and vectorization.", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Provides a hint towards boolean filtering syntax.", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover column creation and vectorized math. However, the use of '.mean()' as a method on a column, the '.map()' method, and 'lambda' functions are entirely missing. A student without prior knowledge would struggle to verify if '.map(lambda x: ...)' is valid syntax or how '.mean()' works.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Crucial Pandas methods (map, mean) and Python functional features (lambda) are not demonstrated in any selectable snippet.", + "missing_concepts": [ + "Series.mean()", + "Series.map()", + "lambda functions in pandas context" + ], + "proposed_fix": "Add a snippet demonstrating how to calculate a column mean and use .map(lambda x: ...) to create conditional columns." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: mean_val = df['col'].mean(); df['new'] = df['col'].map(lambda x: x > mean_val).", + "why_helpful": "It covers both .mean() and the map/lambda pattern used in Option B, which are currently opaque to a zero-knowledge user.", + "why_maybe_unnecessary": "Vectorized operations are preferred, but the question explicitly tests these alternatives.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:16:32Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:resit-solutions-for-introduction-to-python-35761538-q24", + "question_id": "resit-solutions-for-introduction-to-python-35761538-q24", + "exam_id": "resit-solutions-for-introduction-to-python-35761538", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "pandas - lambda - 3", + "question": "What will be the output of the following lines of code?\n\nimport pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)", + "options": { + "a": "A B C\n0 1 4 16\n1 2 5 17\n2 3 6 18", + "b": "A B C\n0 1 4 18\n1 2 5 21\n2 3 6 24", + "c": "A B C\n0 1 4 12\n1 2 5 15\n2 3 6 18", + "d": "A B C\n0 1 4 9\n1 2 5 12\n2 3 6 15" + }, + "correct": "a", + "explanation": "df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing 16, 17, and 18 in column C.", + "code_context": "import pandas as pd\n\ndf = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]})\ndf['C'] = df['A'].map(lambda x: x + df['B'].sum())\n\nprint(df)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions the .map() method and explains that it allows applying a function to a Series, which is the central operation in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions the .map() method and explains that it allows applying a function to a Series, which is the central operation in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows the pattern of creating a new column ('C') in an existing DataFrame, helping the student understand the assignment part of the code." + }, + { + "item_id": "cs-b46633d18d", + "rationale": "Provides the syntax for DataFrame initialization using a dictionary, which allows the student to parse the first few lines of the code context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "cs-b46633d18d", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet explicitly mentions the .map() method and explains that it allows applying a function to a Series, which is the central operation in the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows the pattern of creating a new column ('C') in an existing DataFrame, helping the student understand the assignment part of the code.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:cs-b46633d18d", + "rationale": "Provides the syntax for DataFrame initialization using a dictionary, which allows the student to parse the first few lines of the code context.", + "critical_piece_ids": [ + "cs-b46633d18d" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:cs-b46633d18d", + "rationale": "", + "needed_piece_ids": [ + "cs-b46633d18d" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets cover DataFrame creation and the existence of .map(), there is no information explaining the 'lambda' syntax or the Series '.sum()' method. A zero-knowledge student would not understand that 'x' in the lambda refers to the values in column 'A' or that '.sum()' results in a single scalar value added to each element.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to explain anonymous functions (lambdas) and aggregation methods like .sum().", + "missing_concepts": [ + "lambda functions syntax (lambda x: ...)", + "Series.sum() aggregation method", + "scoping of variables inside a lambda when used with .map()" + ], + "proposed_fix": "Add a snippet or example piece that explains lambda functions in the context of Pandas operations, and a piece demonstrating Series aggregation methods." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for 'Lambda Functions': 'A lambda function is a small anonymous function defined with the lambda keyword. Syntax: lambda x: expression. In df[\"A\"].map(lambda x: x + 5), x represents each element in column A, and 5 is added to each.'", + "why_helpful": "It directly addresses the most confusing part of the code for a beginner.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "edit_existing", + "target_item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "proposal": "Update the rationale/search text to include a lambda example: 'The .map() method allows applying a function (often a lambda, like lambda x: x + 1) to every element in a Series.'", + "why_helpful": "Provides immediate context for how .map() is commonly used in exams.", + "why_maybe_unnecessary": "Might make the snippet too specific to one use case.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:17:51Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:cs-b46633d18d", + "snippet_label": "Combining Data", + "week": 5, + "topic": "Combining Data", + "pieces": [ + { + "item_id": "cs-b46633d18d", + "item_type": "source_notebook", + "bucket": "recommended", + "topic": "Combining Data", + "subtopic_title": "", + "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noo" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q01", + "question_id": "sample-final-plus-answers-q01", + "exam_id": "sample-final-plus-answers", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "vehicle class defaults", + "question": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation.\nThe name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string \"land\".\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A correctly defines the constructor with `self`, stores both attributes on the instance, and gives `vehicle_mode` the default value `\"land\"`.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "While it doesn't cover classes, it is the only family that mentions 'Arguments' and shows the syntax for default values (e.g., factor=2) which is a core part of the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "While it doesn't cover classes, it is the only family that mentions 'Arguments' and shows the syntax for default values (e.g., factor=2) which is a core part of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "Provides a hint towards default argument syntax, although insufficient for the full class structure." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece contains the exact text of the question regarding the Vehicle class and its attributes." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "This piece is a near-identical duplicate of the question, providing the same scenario about the Vehicle class." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "While it doesn't cover classes, it is the only family that mentions 'Arguments' and shows the syntax for default values (e.g., factor=2) which is a core part of the question.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "Provides a hint towards default argument syntax, although insufficient for the full class structure.", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The available non-identical snippets do not explain 'class' syntax, the '__init__' constructor, or the requirement of the 'self' parameter. A student with zero knowledge would not be able to distinguish between the options based on the provided logic alone.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a total lack of OOP syntax documentation (classes, constructors, self) outside of the near-identical exam questions.", + "missing_concepts": [ + "class definition syntax", + "__init__ method purpose and syntax", + "self parameter in instance methods", + "instance attribute assignment (self.name = ...)" + ], + "proposed_fix": "Add a foundational OOP snippet that shows a simple class definition with a constructor, usage of self, and default arguments." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Class Basics' snippet: 'class MyClass:\\n def __init__(self, required_val, optional_val=\"default\"):\\n self.attr1 = required_val\\n self.attr2 = optional_val'", + "why_helpful": "This would directly allow a student to recognize the correct syntax for a class constructor and default arguments.", + "why_maybe_unnecessary": "Only if we assume students should learn this from the identical past exam questions, which violates the goal of general snippet utility.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:18:13Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q02", + "question_id": "sample-final-plus-answers-q02", + "exam_id": "sample-final-plus-answers", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "book rating output", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The stored review scores are 5, 3, and 3. Their average is 11 / 3 = 3.666..., and the method rounds that to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "Contains a nearly identical code example (manual-oop-state-compare) that demonstrates tracing state in a Book class with add_review and average calculation." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Contains a nearly identical code example (manual-oop-state-compare) that demonstrates tracing state in a Book class with add_review and average calculation." + }, + { + "item_id": "aiq-2", + "rationale": "Explains list method effects (append) and the default None return behavior, which helps confirm why 'c' might be an option but isn't the answer here." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Matches the question text, code, and scenario (Book class with add_review and show_rating) exactly." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "rationale": "Matches the question text and scenario exactly." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "Contains a nearly identical code example (manual-oop-state-compare) that demonstrates tracing state in a Book class with add_review and average calculation.", + "critical_piece_ids": [ + "manual-oop-state-compare", + "manual-oop-init-defaults" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "Explains list method effects (append) and the default None return behavior, which helps confirm why 'c' might be an option but isn't the answer here.", + "critical_piece_ids": [ + "aiq-2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "", + "needed_piece_ids": [ + "manual-oop-state-compare", + "manual-oop-init-defaults" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam pieces provide the answer directly. Even excluding them, the OOP Fundamentals core snippet provides a high-fidelity template for the logic, though it lacks an explicit definition of the 'round()' function.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main logic (OOP state, list appending, averaging) is well-covered, but the specific behavior of the 'round(x, 1)' function is not explicitly defined in the general snippets.", + "missing_concepts": [ + "round(number, ndigits)" + ], + "proposed_fix": "Add a small example or key point demonstrating how 'round(number, 1)' rounds to one decimal place." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a Key Point: 'The round(value, n) function rounds a number to n decimal places. For example, round(3.666, 1) results in 3.7.'", + "why_helpful": "The question hinges on the distinction between 3.66... (unrounded), 3.67 (rounded to 2 places), and 3.7 (rounded to 1 place).", + "why_maybe_unnecessary": "Rounding is a common mathematical concept that students may already know, but seeing the Python syntax 'round(x, 1)' confirms the behavior.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:18:37Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book" + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-oop-state-compare", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.sc" + }, + { + "item_id": "manual-oop-compare-none-case", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Return `None` when neither object clearly wins\nclass Book:\n def __init__(self, title, scores):\n self.title = title\n self.scores = scores\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def winner_against(self, other):\n if se" + }, + { + "item_id": "manual-oop-init-defaults", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state " + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + }, + { + "item_id": "kp-manual-self-attr", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Use `self.attr = ...` to store per-object state. A bare assignment like `attr = ...` inside a method only creates or updates a local variable." + }, + { + "item_id": "manual-oop-attrs", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Class attribute vs instance attribute\nclass Rectangle:\n units = 'cm'\n\n def __init__(self, width):\n self.width = width\n\nr1 = Rectangle(3)\nr2 = Rectangle(5)\nr2.units = 'm'\nprint(r1.units, r2.units)\n`self.width` is per object; `Class.units` is shared until an instance s" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-22-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-22-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q03", + "question_id": "sample-final-plus-answers-q03", + "exam_id": "sample-final-plus-answers", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "student grade formatting", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\nFor example, if\nstudents = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 75.\nBernard has received a grade of 80.\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']}. \")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {student['Grade']}. \")", + "c": "for student in students:\n print(f\"{student['Name']} has received a grade of \" + str(student[\"Grade\"]))", + "d": "for student, grade in students.items():\n print(f'{student} has received a grade of {grade}.')" + }, + "correct": "a", + "explanation": "Option A iterates through the list of dictionaries and prints each student's name together with that student's grade. The other options incorrectly call `.items()` on the list or use the wrong data access pattern.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 75}, {\"Name\": \"Bernard\", \"Grade\": 80}]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Of the non-identical candidates, this is the most relevant as it deals with the relationship between lists and dictionaries, helping a student identify how to work with dictionary keys/values even though it doesn't show list-of-dictionary iteration." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Of the non-identical candidates, this is the most relevant as it deals with the relationship between lists and dictionaries, helping a student identify how to work with dictionary keys/values even though it doesn't show list-of-dictionary iteration." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides context on mapping lists of names and ages into dictionaries, reinforcing the data structure pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Contains the exact 'students' list prompt and requirements found in the current question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Another exact match for the 'students' list dictionary iteration problem." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Of the non-identical candidates, this is the most relevant as it deals with the relationship between lists and dictionaries, helping a student identify how to work with dictionary keys/values even though it doesn't show list-of-dictionary iteration.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides context on mapping lists of names and ages into dictionaries, reinforcing the data structure pattern.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question appears in two different candidate snippet families. A student with zero knowledge can match the prompt and structure to find the solution.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While direct hits exist, there is no general conceptual guidance explaining the difference between iterating over a list vs. a dictionary (specifically why .items() fails on a list).", + "missing_concepts": [ + "Iterating over a list of dictionaries vs. a dictionary", + "f-string precision formatting (e.g., :.1f)", + "Dictionary key access syntax within a loop" + ], + "proposed_fix": "Add a general-purpose 'f-string and Data Structures' snippet that explains how to loop through a list of dictionaries and format values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Syntax: Loops & Dictionaries' piece. Example: 'When you have a list of dicts, use: for item in my_list: print(item[\"key\"])'. Also include f-string formatting: '{value:.1f}' for decimals.", + "why_helpful": "The question explicitly mentions a decimal place requirement that isn't clearly explained in any non-identical snippet, and it clarifies why options B/D (using .items()) are incorrect for a list.", + "why_maybe_unnecessary": "The direct past-exam matches already provide the solution for this specific exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:19:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q04", + "question_id": "sample-final-plus-answers-q04", + "exam_id": "sample-final-plus-answers", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "phone number formatting", + "question": "You need to write a function called format_phone_number that formats phone numbers.\nThe output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) at various places.\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A calls `replace` but does not store its result, so it returns the original unchanged string. The other options all build and return the digits without the dashes.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# should all return \"0205251400\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "The 'Objects and Names' piece explains the difference between rebinding a name and mutating an object. This is critical for understanding why Option A fails: `number.replace` creates a new string object but the code fails to rebind the name `number` to that new object." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "The 'Objects and Names' piece explains the difference between rebinding a name and mutating an object. This is critical for understanding why Option A fails: `number.replace` creates a new string object but the code fails to rebind the name `number` to that new object." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Return Behavior' and 'Objects and Names' pieces emphasize tracing returned values and how functions handle assignments, which helps identify that the ignored return value in Option A is the root cause." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This piece contains the exact question text and context provided in the question JSON." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-5", + "rationale": "The 'Objects and Names' piece explains the difference between rebinding a name and mutating an object. This is critical for understanding why Option A fails: `number.replace` creates a new string object but the code fails to rebind the name `number` to that new object.", + "critical_piece_ids": [ + "aiq-5" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Return Behavior' and 'Objects and Names' pieces emphasize tracing returned values and how functions handle assignments, which helps identify that the ignored return value in Option A is the root cause.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the conceptual snippets explain mutation vs. rebinding, there is no snippet in the candidate list (other than the identical exam question) that explains the specific behavior of string methods like .replace(), .split(), or .join(). A student with zero knowledge would not know what these methods do.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets explain general name-binding concepts but lack specific documentation on string methods and string immutability.", + "missing_concepts": [ + "String immutability (strings cannot be changed in place)", + "Behavior of str.replace() (returns a NEW string)", + "Behavior of str.split() and str.join() for string cleanup" + ], + "proposed_fix": "Add a summary snippet covering core string operations (replace, split, join, strip) and explicitly stating that strings are immutable in Python." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Methods and Immutability. Content: In Python, strings are immutable (cannot be changed). Methods like .replace(), .upper(), and .split() return a NEW string/list and do not modify the original. To save the change, you must reassign the variable: x = x.replace('-', ''). Use ''.join(list) to combine a list of strings into one string.", + "why_helpful": "This directly addresses the logic gap in identifying why option A (which doesn't reassign) fails while option B (which returns the result directly) succeeds.", + "why_maybe_unnecessary": "The trial exam piece already contains the question, but this general snippet would help for other similar questions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:19:49Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q05", + "question_id": "sample-final-plus-answers-q05", + "exam_id": "sample-final-plus-answers", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "pandas even-row selection", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.9\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that looks like this, when printed:\n\n B\n2 8.2\n4 3.6\n6 8.4\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters the even-numbered row labels and keeps column `B` as a one-column DataFrame, matching the printed target. The other options use invalid indexing, select the wrong column/positions, or return a Series instead of the shown DataFrame.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "While it focuses on column addition, it is the only non-identical snippet showing basic Pandas DataFrame structure and column access syntax (df['C'] = ...), providing essential context for DataFrame operations." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "While it focuses on column addition, it is the only non-identical snippet showing basic Pandas DataFrame structure and column access syntax (df['C'] = ...), providing essential context for DataFrame operations." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces the concept of vectorized operations in Pandas, which is relevant to the boolean masking logic used in the correct answer." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This piece contains the exact same question logic (indices 2, 4, 6 and column 'B') and explicitly explains that Option A uses a boolean mask on the index to find even numbers." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Matches the exact DataFrame values and question structure regarding row/column selection." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "While it focuses on column addition, it is the only non-identical snippet showing basic Pandas DataFrame structure and column access syntax (df['C'] = ...), providing essential context for DataFrame operations.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces the concept of vectorized operations in Pandas, which is relevant to the boolean masking logic used in the correct answer.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include two nearly identical past exam questions that cover the exact DataFrame and the specific logic (modulo on index + .loc filtering). One even explicitly explains why the correct option works.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The concepts of .loc indexing, boolean masking, and the modulo operator for row filtering are currently only available via past exam questions rather than general instructional snippets.", + "missing_concepts": [ + ".loc indexing vs .iloc", + "Boolean masking on DataFrame indices", + "Modulo operator usage for even/odd row selection" + ], + "proposed_fix": "Add a general-purpose snippet for 'Pandas Indexing and Filtering' that explains selecting rows by labels vs positions and using logical conditions/math on indices." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas Filtering with .loc\nContent: Use `df.loc[condition, [columns]]` to filter rows and select columns. To select even-labeled rows, use `df.index % 2 == 0` as the condition. `df.loc[:, ['B']]` returns a DataFrame, while `df['B']` often returns a Series.", + "why_helpful": "Provides the underlying conceptual logic for indexing and filtering without relying on an identical past exam answer.", + "why_maybe_unnecessary": "The student can find the answer in the past exam bank, but won't understand the 'why' for variants.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:20:32Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q06", + "question_id": "sample-final-plus-answers-q06", + "exam_id": "sample-final-plus-answers", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "pandas df2 derivation", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False).loc[:, [\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A would keep all five rows after sorting the index descending, so it would not produce the shown three-row df2. The other options can all produce rows 4, 3, and 2 with columns A, C, and D in the displayed order.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This is the best non-identical snippet as it establishes the context of inspecting and selecting data from a pandas DataFrame with a similar structure, although it lacks the specific method explanations." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This is the best non-identical snippet as it establishes the context of inspecting and selecting data from a pandas DataFrame with a similar structure, although it lacks the specific method explanations." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates basic DataFrame column manipulation, helping the student recognize pandas syntax patterns." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This piece contains the exact same question and a detailed explanation that directly identifies Option A as incorrect because it results in 5 rows instead of 3." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This is the best non-identical snippet as it establishes the context of inspecting and selecting data from a pandas DataFrame with a similar structure, although it lacks the specific method explanations.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Demonstrates basic DataFrame column manipulation, helping the student recognize pandas syntax patterns.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The student can answer correctly because one of the provided snippets is the exact question with the answer and explanation included. Without that specific piece, the other snippets provide context but no logic for loc/iloc/sorting.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate snippets lack a general conceptual explanation of 'loc' vs 'iloc', slicing behavior, and sorting methods ('sort_index', 'sort_values').", + "missing_concepts": [ + "pandas loc vs iloc", + "pandas sorting (sort_index, sort_values)", + "pandas slicing inclusive/exclusive rules" + ], + "proposed_fix": "Add a summary table or 'Key Points' piece explaining how loc/iloc handle indices and how sort_values affects row order." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Pandas Selection & Sorting' cheat sheet piece. It should explain: 1. loc uses labels and is inclusive of the end. 2. iloc uses integer positions and is exclusive of the end. 3. sort_index() vs sort_values(by=...). 4. How selection can reduce row counts.", + "why_helpful": "It would allow a student to solve this and similar derivation questions through logic rather than relying on finding a near-identical past exam question.", + "why_maybe_unnecessary": "The current dataset contains many exam questions that may indirectly cover these through osmosis, but a direct reference is more reliable.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:21:49Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "Which of the following code lines could NOT have created df2 from df1?\nA\nB\nC\nD\nA\nOption A would sort all 5 rows of df1 and keep columns A, C, D, resulting in a 5-row DataFrame. df2 only has 3 rows (indices 4, 3, 2)." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)\nA\nB\nC\nD\nA\n'3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is False. x == y == z evaluates as (x == y) and (y == z), which is False and True, resulting in False." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q07", + "question_id": "sample-final-plus-answers-q07", + "exam_id": "sample-final-plus-answers", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "datetime month parser", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "`\"03/02/2013\"` is parsed with `%m/%d/%Y`, so its month is 3. `\"03.02.2013\"` matches neither separator rule and becomes `None`. `\"03-02-2013\"` is parsed with `%d-%m-%Y`, so its month is 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "As a near-identical past exam piece, it provides the full solution and logic for the specific datetime parsing rules mentioned in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "As a near-identical past exam piece, it provides the full solution and logic for the specific datetime parsing rules mentioned in the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Demonstrates string searching for characters (like '-') and processing input strings, which is the mechanical basis of the question's logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This is the exact same question from a past exam, including the same date strings and logic explanation." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "As a near-identical past exam piece, it provides the full solution and logic for the specific datetime parsing rules mentioned in the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Demonstrates string searching for characters (like '-') and processing input strings, which is the mechanical basis of the question's logic.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-9-w6-datetime" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question and its step-by-step logic are present in the 'Datetime' snippet family.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the identical question exists, a general-purpose snippet explaining strptime tokens (%d, %m, %Y) would be better for students who don't just want to memorize the answer.", + "missing_concepts": [ + "datetime.strptime format tokens", + "list comprehensions with if/else" + ], + "proposed_fix": "Add a conceptual snippet for Datetime formatting that defines what %d, %m, and %Y represent." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A 'Datetime Cheatsheet' snippet showing: datetime.strptime(string, format). Tokens: %d (day), %m (month), %Y (4-digit year). Example: strptime('03-02', '%d-%m') -> Day 3, Month 2.", + "why_helpful": "It enables the student to solve any variation of this problem (e.g., if the order of %d and %m is swapped) rather than relying on finding the exact past exam question.", + "why_maybe_unnecessary": "The exact question is already in the database, so for this specific exam, the student is already covered.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:22:00Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?\nA\nB\nC\nD\nA\n1st string: contains '/' so it uses %m/%d/%Y -> month 3. 2nd: contains neither '-' nor '/' -> None. 3rd: contains '-' so it uses %d-" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q08", + "question_id": "sample-final-plus-answers-q08", + "exam_id": "sample-final-plus-answers", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "dictionary comprehension lengths", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the only dictionary comprehension that maps each string to its own length. Option B makes a list, Option C makes a set, and Option D reverses the intended key-value direction.", + "code_context": "list_1 = [ ... ]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the standard dictionary format `{key: value}`, which helps a novice identify that a dictionary requires both a key and a value separated by a colon, helping eliminate Option B and C." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the standard dictionary format `{key: value}`, which helps a novice identify that a dictionary requires both a key and a value separated by a colon, helping eliminate Option B and C." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "The explanation mentions that `{...}` can result in a set (Option C), helping the student understand that curly braces are used for both sets and dictionaries." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Provides another example of mapping keys to values in a dictionary context, reinforcing the conceptual mapping required by the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This is an exact duplicate of the provided question, including the same list name ('list_1'), logic, and options." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Nearly identical question that maps a list of strings ('words') to their lengths in a dictionary, demonstrating the exact code pattern required." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the standard dictionary format `{key: value}`, which helps a novice identify that a dictionary requires both a key and a value separated by a colon, helping eliminate Option B and C.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "The explanation mentions that `{...}` can result in a set (Option C), helping the student understand that curly braces are used for both sets and dictionaries.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Provides another example of mapping keys to values in a dictionary context, reinforcing the conceptual mapping required by the question.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "After excluding the identical exam pieces, none of the remaining snippets explain the 'for item in list' comprehension syntax within curly braces. A student with zero Python knowledge wouldn't know how to construct the dictionary dynamically or what the 'len()' function does.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The collection lacks a general conceptual explanation of Python comprehensions and basic built-in functions like 'len()'.", + "missing_concepts": [ + "dictionary comprehension syntax", + "the len() function for string length", + "distinction between set and dictionary comprehension syntax" + ], + "proposed_fix": "Add a dedicated 'Python Basics: Comprehensions' snippet that shows the syntax `{k: v for x in y}` for dictionaries and explains the `len()` function." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet family 'Python Syntax: Collections & Comprehensions' with a piece showing list, set, and dictionary comprehension examples side-by-side.", + "why_helpful": "This allows students to identify the correct syntax for a dictionary (Option A) versus a set (Option C) or a list (Option B) without relying on matching identical past exam questions.", + "why_maybe_unnecessary": "Memorizing the identical past exam questions provided in the 'near_identical' section would suffice for this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:22:51Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?\nA\nB\nC\nD\nA\nThis is a standard dictionary comprehension. Option B is a list comprehension, Option C is a se" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q09", + "question_id": "sample-final-plus-answers-q09", + "exam_id": "sample-final-plus-answers", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "Datetime parsing", + "question": "Take a look at the following code segment.\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "The first string contains `/`, so it is parsed as month/day/year and gives month 3. The second string contains neither `-` nor `/`, so it becomes `None`. The third contains `-`, so it is parsed as day-month-year and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about datetime, it provides a parallel logic example where a function processes a string input containing specific characters ('-') to determine formatting, which helps a student understand conditional string processing." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about datetime, it provides a parallel logic example where a function processes a string input containing specific characters ('-') to determine formatting, which helps a student understand conditional string processing." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Demonstrates the structural pattern of iterating through a list and conditionally appending results to a new list, which is the core structure of the get_months function." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This is the exact same question, providing the code, the call, and an explanation of why each string is parsed differently." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about datetime, it provides a parallel logic example where a function processes a string input containing specific characters ('-') to determine formatting, which helps a student understand conditional string processing.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "rationale": "Demonstrates the structural pattern of iterating through a list and conditionally appending results to a new list, which is the core structure of the get_months function.", + "critical_piece_ids": [ + "exam-trial_midterm-6-w2-conditions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-trial_midterm-6-w2-conditions" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The identical past exam piece provides the answer directly. If excluded, there are no general snippets explaining Datetime format codes (%d, %m, %Y). While a student might guess that 'm' stands for month and 'd' for day, they would lack confirmation without a specific datetime reference.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is no general reference for the datetime module, specifically for strptime and its format codes.", + "missing_concepts": [ + "datetime.strptime() function purpose", + "Datetime format codes: %d (day), %m (month), %Y (4-digit year)", + "Datetime object attributes: .month" + ], + "proposed_fix": "Add a general-purpose 'Datetime Basics' snippet." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime Formatting' snippet: \n- Explain datetime.strptime(string, format).\n- Table of codes: %d (Day 01-31), %m (Month 01-12), %Y (Year 2023), %y (Year 23).\n- Example: datetime.strptime('25-12-2022', '%d-%m-%Y').month returns 12.", + "why_helpful": "Provides the necessary semantic knowledge to decode the logic in the question without needing to see the identical exam item.", + "why_maybe_unnecessary": "The logic might be inferable if the student assumes 'm' = month, but explicit documentation is safer for 'zero knowledge' users.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:23:32Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?\nA\nB\nC\nD\nA\n1st string: contains '/' so it uses %m/%d/%Y -> month 3. 2nd: contains neither '-' nor '/' -> None. 3rd: contains '-' so it uses %d-" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q10", + "question_id": "sample-final-plus-answers-q10", + "exam_id": "sample-final-plus-answers", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "Datetime day-of-year", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives a `timedelta`; taking `.days` and adding 1 makes January 1 equal to day 1. The other options either misuse `timedelta`, add an integer directly to a `datetime` difference, or use an invalid date.", + "code_context": "day_of_year(datetime(2022, 2, 1))\n# should return 32" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly addresses the problem of calculating the day-of-year using datetime subtraction and the .days attribute." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly addresses the problem of calculating the day-of-year using datetime subtraction and the .days attribute." + }, + { + "item_id": "aiq-4", + "rationale": "Contains general Python logic like '1 + True = 2', which helps understand why adding 1 to an integer difference is valid, though less critical than the direct exam match." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the exact same question from a different exam version, providing both the logic and the explanation for why option A is correct." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "Directly addresses the problem of calculating the day-of-year using datetime subtraction and the .days attribute.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "Contains general Python logic like '1 + True = 2', which helps understand why adding 1 to an integer difference is valid, though less critical than the direct exam match.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the identical question and its explanation from a past exam, making the correct answer explicitly clear.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "No gaps exist as the exact question is present in the snippets.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:23:42Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q11", + "question_id": "sample-final-plus-answers-q11", + "exam_id": "sample-final-plus-answers", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary comprehension", + "question": "You have a list of strings called list_1, in which every element is unique.\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Only option A is a dictionary comprehension with each string as the key and its length as the value. The others create a list, a set, or a dictionary with the mapping reversed.", + "code_context": "list_1 = [...]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Although it is an identical question, its explanation explicitly identifies the syntax types (dictionary comprehension vs list/set comprehension), which provides the necessary conceptual definitions to distinguish the options." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Although it is an identical question, its explanation explicitly identifies the syntax types (dictionary comprehension vs list/set comprehension), which provides the necessary conceptual definitions to distinguish the options." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the standard curly-brace and colon syntax for dictionaries '{key: value}', helping a student recognize the dictionary structure in options A and D vs option B (list) and C (set)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This is an exact duplicate of the current question, including the same options and correct answer 'A'." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This is a near-identical question asking to create a dictionary of word lengths from a list, which mirrors the logic and correct answer structure of the current question." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Although it is an identical question, its explanation explicitly identifies the syntax types (dictionary comprehension vs list/set comprehension), which provides the necessary conceptual definitions to distinguish the options.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the standard curly-brace and colon syntax for dictionaries '{key: value}', helping a student recognize the dictionary structure in options A and D vs option B (list) and C (set).", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question and answer are present in the snippets. Even without identical matches, the explanation in the best snippet defines 'dictionary comprehension' which matches option A's syntax.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets rely entirely on past exam duplicates. There is no general documentation snippet explaining the syntax and mechanics of dictionary comprehensions (key: value for item in iterable).", + "missing_concepts": [ + "Dictionary Comprehension syntax", + "List vs Set vs Dictionary comprehension visual patterns" + ], + "proposed_fix": "Add a general syntax snippet for Dictionary Comprehensions showing the template {key_expr: value_expr for item in iterable}." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Dictionary Comprehensions\nContent: You can create a dictionary in one line using a comprehension:\n`new_dict = {key_expression: value_expression for item in list_or_range}`\nExample:\n`lengths = {word: len(word) for word in ['apple', 'hi']}` results in `{'apple': 5, 'hi': 2}`.", + "why_helpful": "Provides a general rule rather than relying on a past exam spoiler, allowing the student to understand the mapping logic (key vs value position).", + "why_maybe_unnecessary": "The student can already find the exact answer in the 'near_identical' exam items.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:24:11Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?\nA\nB\nC\nD\nA\nThis is a standard dictionary comprehension. Option B is a list comprehension, Option C is a se" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q12", + "question_id": "sample-final-plus-answers-q12", + "exam_id": "sample-final-plus-answers", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "Case swapping", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[x if x in 'abcdefghijklmnopqrstuvwxyz'.upper() else x.lower() for x in list_1]", + "c": "Both achieve what you want", + "d": "None achieves what you want" + }, + "correct": "a", + "explanation": "Option A explicitly checks whether each character is lowercase and flips the case accordingly. Option B leaves uppercase letters unchanged instead of converting them to lowercase.", + "code_context": "list_1 = [...]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides context for handling string variables (alphabet) and list conversions, which is relevant to understanding the string 'abcdefg...' used in Option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides context for handling string variables (alphabet) and list conversions, which is relevant to understanding the string 'abcdefg...' used in Option B." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Introduces the concept of iterating through a list (students) which is the fundamental structure of the list comprehensions used in all options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-12-w2-conditions", + "rationale": "This past exam question is nearly identical, asking about turning uppercase letters to lowercase and vice versa in a list, though the options/correct answer might differ slightly in implementation details." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Provides context for handling string variables (alphabet) and list conversions, which is relevant to understanding the string 'abcdefg...' used in Option B.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "Introduces the concept of iterating through a list (students) which is the fundamental structure of the list comprehensions used in all options.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of a near-identical past exam question (intro_python_sample_final_24_25-12) makes the correct logic and solution structure immediately obvious to a student, even with the slightly conflicting 'Both' vs 'Option A' correctness.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the identical exam question provides the answer, there is no general educational snippet explaining the syntax of list comprehensions with if-else conditions or the specific string methods .islower(), .upper(), and .lower().", + "missing_concepts": [ + "List comprehension with if-else syntax", + "String case methods (.upper(), .lower(), .islower())", + "The 'in' operator for substring/membership checks" + ], + "proposed_fix": "Add a topic card under 'String Operations' that explicitly lists case-checking and case-conversion methods, and a 'Comprehensions' card showing the 'value if condition else other_value for item in list' syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Case Methods. Content: .upper() converts to uppercase, .lower() to lowercase, and .islower()/.isupper() return True if the string is entirely that case.", + "why_helpful": "Directly explains the components of Option A.", + "why_maybe_unnecessary": "The identical past exam question might be sufficient for a student to guess correctly.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Conditional List Comprehensions. Content: [x if condition else y for x in list_1] allows you to transform elements based on a logic check.", + "why_helpful": "Explains the structure used in the options, which is different from a standard [x for x in list if condition] filter.", + "why_maybe_unnecessary": "None of the other non-exam snippets show this syntax currently.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:24:41Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-12-w2-conditions", + "snippet_label": "Comprehensions", + "week": 6, + "topic": "Comprehensions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this?\nA\nB\nC\nD\nC\nBoth options implement the conditional logic required to flip the case of each character in the list." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q13", + "question_id": "sample-final-plus-answers-q13", + "exam_id": "sample-final-plus-answers", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Comparisons and types", + "question": "Suppose you have three variables x, y, z, as follows:\nx = '3'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string `'3'` is not equal to the integer `3`, while `3 == 3.0` is `True`. The chained comparison `x == y == z` means `(x == y) and (y == z)`, so it is `False`.", + "code_context": "x = '3'\ny = 3\nz = 3.0" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Excluding the identical question, this is the best general snippet because it uses the exact same variable values ('3', 3, 3.0) to test the distinction between strings, integers, and floats in comparisons." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Excluding the identical question, this is the best general snippet because it uses the exact same variable values ('3', 3, 3.0) to test the distinction between strings, integers, and floats in comparisons." + }, + { + "item_id": "aiq-5", + "rationale": "Provides a variation of the same comparison logic, reinforcing that strings and integers with the same numeric character are not considered equal in Python." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "This piece is an exact match for the question, featuring the same variables (x, y, z), the same comparison operations, and a detailed explanation of why each result is True or False." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "rationale": "Excluding the identical question, this is the best general snippet because it uses the exact same variable values ('3', 3, 3.0) to test the distinction between strings, integers, and floats in comparisons.", + "critical_piece_ids": [ + "exam-midterm_2024-2-w2-conditions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "rationale": "Provides a variation of the same comparison logic, reinforcing that strings and integers with the same numeric character are not considered equal in Python.", + "critical_piece_ids": [ + "aiq-5" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-2-w2-conditions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam question provides the complete answer and explanation. Even without it, the 'Conditions' snippet clarifies the type-mismatch behavior for the specific values used in the question.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The main gap (excluding the identical question) is an explicit explanation of comparison chaining logic.", + "missing_concepts": [ + "chained comparisons (a == b == c)" + ], + "proposed_fix": "Add a conceptual snippet explaining that Python evaluates 'x == y == z' as '(x == y) and (y == z)'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Chained Comparisons: Python allows chaining comparisons like `x == y == z`. This is evaluated as `(x == y) and (y == z)`. If the first comparison is False, the entire expression becomes False without checking the rest.", + "why_helpful": "This specifically addresses the logic behind the final print statement in the question, which is a common stumbling block for beginners.", + "why_maybe_unnecessary": "The identical exam snippet already explains this, but a standalone concept piece would be more versatile for other questions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:25:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)\nA\nB\nC\nD\nA\n'3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is False. x == y == z evaluates as (x == y) and (y == z), which is False and True, resulting in False." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q14", + "question_id": "sample-final-plus-answers-q14", + "exam_id": "sample-final-plus-answers", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Loops", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. (In the first iteration, just take the previous number to be 0.)\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e.: only the sums).", + "options": { + "a": "i = 0\nwhile i <= 10:\n print(i + (i-1))\n i += 1", + "b": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "b", + "explanation": "Option B correctly tracks the previous number and starts the loop at 1, producing the required sums. Option A starts at 0 and prints `-1` on the first iteration, so it does not match the specification.", + "code_context": "# target outputs: 1, 3, 5, ..., 19" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-loop-max-sublist-sum", + "rationale": "This family provides the most relevant logical patterns, specifically illustrating state management (tracking a 'best' or 'current' value) which mirrors the 'previous' variable logic in the question." + }, + "top_three_snippets": [ + { + "item_id": "manual-loop-max-sublist-sum", + "rationale": "This family provides the most relevant logical patterns, specifically illustrating state management (tracking a 'best' or 'current' value) which mirrors the 'previous' variable logic in the question." + }, + { + "item_id": "kp-manual-loop-core-d1", + "rationale": "Provides a high-level summary of loop types and when to use them, helping distinguish between the 'for' and 'while' options provided in the question." + }, + { + "item_id": "ks-bddafc66a0", + "rationale": "Shows basic for-loop syntax and the relationship between the loop variable and the sequence, which is fundamental to evaluating the options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "" + }, + { + "item_id": "manual-loop-max-sublist-sum", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "snippet_id": "item:exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "This is the exact same question and answer pair as the target question, confirming Option B is correct." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "rationale": "This family provides the most relevant logical patterns, specifically illustrating state management (tracking a 'best' or 'current' value) which mirrors the 'previous' variable logic in the question.", + "critical_piece_ids": [ + "manual-loop-max-sublist-sum", + "ai-example-3" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:kp-manual-loop-core-d1", + "rationale": "Provides a high-level summary of loop types and when to use them, helping distinguish between the 'for' and 'while' options provided in the question.", + "critical_piece_ids": [ + "kp-manual-loop-core-d1" + ] + }, + { + "snippet_id": "item:ks-bddafc66a0", + "rationale": "Shows basic for-loop syntax and the relationship between the loop variable and the sequence, which is fundamental to evaluating the options.", + "critical_piece_ids": [ + "ks-bddafc66a0" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops" + ] + }, + { + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "rationale": "", + "needed_piece_ids": [ + "manual-loop-max-sublist-sum" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of a near-identical past exam question makes the answer certain. Even without it, the combination of loop syntax and state-tracking examples (manual-loop-max-sublist-sum) provides a strong logical basis for a student to select the correct code pattern.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is provided directly in a past exam piece, the general snippets lack a clear definition of range(start, stop) behavior (start is inclusive, stop is exclusive).", + "missing_concepts": [ + "range(start, stop) exclusivity" + ], + "proposed_fix": "Add a specific key point or example demonstrating that range(1, 11) generates numbers 1 through 10." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a piece to a Loop-related snippet: 'range(start, stop) generates numbers starting at `start` and ending at `stop - 1`. For example, range(1, 11) produces 1, 2, ..., 10.'", + "why_helpful": "The question relies on knowing that range(1, 11) includes 10 but not 11, which is a common source of confusion for beginners.", + "why_maybe_unnecessary": "The near-identical exam piece already explains the correct answer, reducing the immediate need for conceptual clarity to pass this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:26:06Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).\nA\nB\nC\nD\nB\nOption B correctly updates the 'previous' state at the end of each iteration to match the logic of the target output." + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:kp-manual-loop-core-d1", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "kp-manual-loop-core-d1", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Pick the loop shape first\nPattern | Use when | Common exam note\nfor item in seq | you need the values | prefer this over indexing when position is irrelevant\nfor i, item in enumerate(seq, start) | you need both index and value | start defaults to 0\nwhile items: | truthiness contr" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:ks-bddafc66a0", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "ks-bddafc66a0", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "For-loops\nfor variable in sequence: expression. break: exit loop entirely. continue: skip to next iteration. You don't have to use the loop variable; use _ as convention when not needed.\nFor-loop with continue\ntotal = 0\nfor number in [1, 2, '3', 3, 5, 7]:\n if type(number) == s" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "ai-example-3", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Loops", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "search_text": "Loop variable not used — use _\nfor _ in range(5):\n print('Hello') # prints Hello 5 times\nUse `_` when the loop should repeat a fixed number of times but the loop variable itself is not needed.\nHello\nHello\nHello\nHello\nHello" + }, + { + "item_id": "manual-loop-max-sublist-sum", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Loops", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "search_text": "Keep the sub-list whose elements have the largest sum\nlists = [[1, 2], [4, 4], [3, 3, 1]]\nbest = lists[0]\nfor current in lists[1:]:\n if sum(current) > sum(best):\n best = current\nprint(best)\nStore the current best sub-list, compare `sum(current)` with `sum(best)` on each" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Loops", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "search_text": "`enumerate(seq, start=1)`\ncountries = ['Andorra', 'Belgium']\nfor index, country in enumerate(countries, 1):\n print(country, 'has index:', index)\n# Andorra has index: 1\n# Belgium has index: 2\nUse `enumerate` when you need both index and value, and set `start=1` if the numbering" + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Loops", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "search_text": "Skip certain values with `continue`\ntotal = 0\nfor number in [1, 2, '3', 3, 5, 7]:\n if type(number) == str:\n continue\n total += number\nprint(total) # 18\nUse `continue` to ignore the current item and jump straight to the next iteration.\n18" + }, + { + "item_id": "manual-loop-zip-enumerate-membership", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Loops", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "search_text": "Combine `zip`, `enumerate`, unpacking, and membership\nnames = ['Ada', 'Bob', 'Cleo']\nscores = [8, 5]\nfor index, (name, score) in enumerate(zip(names, scores), start=1):\n passed = score in {5, 6, 7, 8, 9, 10}\n print(index, name, passed)\n`zip` stops at the shortest iterable, " + }, + { + "item_id": "ai-example-7", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Loops", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "search_text": "`while items:` repeats until the list is empty\nl1 = [1, 2, 3, 4, 5, 6]\ntotal = 0\nwhile l1: # truthy while list is non-empty\n total += l1[0]\n del l1[0]\nprint(total) # 21\nNon-empty lists are truthy and empty lists are falsy, so `while items:` is a common cons" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q15", + "question_id": "sample-final-plus-answers-q15", + "exam_id": "sample-final-plus-answers", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Functions and scope", + "question": "Executing the following program will produce an error. Why?", + "options": { + "a": "Result is a local name and cannot be referenced outside of the function.", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "`result` is defined inside `cube`, so it exists only within the function scope. The line `print(result)` is outside the function, where that local name is not defined.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "This lecture snippet provides the fundamental rule for local and global scope, explicitly stating that names defined inside a function are only known inside that function." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "This lecture snippet provides the fundamental rule for local and global scope, explicitly stating that names defined inside a function are only known inside that function." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Provides basic context on what functions and print are, which helps a novice understand the code structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "The definition of local scope in this snippet is sufficient to solve the problem by identifying that 'result' is defined inside a function and used outside it." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "This is the exact same question, including the function name 'cube', the variable 'result', and the explanation." + }, + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "rationale": "Logically identical question using a 'power' function instead of 'cube', with the same underlying error regarding local scope." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Logically identical question using a 'power' function and the variable 'result' with local scope." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "This lecture snippet provides the fundamental rule for local and global scope, explicitly stating that names defined inside a function are only known inside that function.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Provides basic context on what functions and print are, which helps a novice understand the code structure.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "The definition of local scope in this snippet is sufficient to solve the problem by identifying that 'result' is defined inside a function and used outside it.", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The lecture snippet 'Scope' explicitly defines that variables assigned inside a function are 'Local names' and 'Only known inside the function'. This directly explains why print(result) outside the function causes an error.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets perfectly cover the concept required (local vs global scope).", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:26:23Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
                • A function is a grouping of code that can perform a certain task and can be re-used \n
                • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:ks-ab66f3bab6", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "ks-ab66f3bab6", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Methods vs functions\nMethods are functions attached to objects. Calling obj.method() is equivalent to Class.method(obj). For mutable objects: some methods CHANGE the object (e.g. list.sort()), some RETURN a value (e.g. list.index()). For immutable objects: methods always return a" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q16", + "question_id": "sample-final-plus-answers-q16", + "exam_id": "sample-final-plus-answers", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "Lambda functions", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "The first lambda returns `1 + 2 = 3`, the second returns `1 * 2 = 2`, and `3 ** 2` equals `9`.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-58858d6d96", + "rationale": "This lecture snippet explains the lambda syntax 'lambda params: expression', explicitly shows a two-argument lambda (x, y: x + y), and demonstrates how to call it." + }, + "top_three_snippets": [ + { + "item_id": "ks-58858d6d96", + "rationale": "This lecture snippet explains the lambda syntax 'lambda params: expression', explicitly shows a two-argument lambda (x, y: x + y), and demonstrates how to call it." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Shows the '**' operator being used for squaring and cubing (n**2, n**3), which is necessary to understand the final calculation in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-58858d6d96", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "snippet_id": "item:exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "This item is the exact same question, including the same list values, the same call using the exponentiation operator, and the same explanation." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-58858d6d96", + "rationale": "This lecture snippet explains the lambda syntax 'lambda params: expression', explicitly shows a two-argument lambda (x, y: x + y), and demonstrates how to call it.", + "critical_piece_ids": [ + "ks-58858d6d96" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Shows the '**' operator being used for squaring and cubing (n**2, n**3), which is necessary to understand the final calculation in the question.", + "critical_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-58858d6d96", + "rationale": "", + "needed_piece_ids": [ + "ks-58858d6d96" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The lecture snippet covers the lambda syntax and calling pattern, while the midterm snippet explains the exponentiation operator. Together they provide all the logic needed to solve the code.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the pieces provide lambda and operator knowledge, they don't explicitly demonstrate that list elements can be callable functions (list[0](...)).", + "missing_concepts": [ + "list indexing with function calls" + ], + "proposed_fix": "Add a small note to the Lambda Basics snippet showing that lambdas can be stored in lists or dictionaries and called via index/key." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-58858d6d96", + "proposal": "Lambda functions\nAnonymous one-line functions. Syntax: lambda params: expression. \nLambda basics\nadd = lambda x, y: x + y\nprint(add(1, 2)) # 3\n# Functions as data\nfuncs = [lambda x: x*2, lambda x: x+10]\nprint(funcs[0](5)) # 10", + "why_helpful": "Explicitly demonstrates that list elements (funcs[0]) can be called like functions, which is the specific structure of the exam question.", + "why_maybe_unnecessary": "Students might intuitively grasp that if add(1,2) works, and funcs[0] is that function, funcs[0](1,2) also works.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:26:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))\nA\nB\nC\nD\nD\nlist_1[0](1, 2) is 1 + 2 = 3. list_1[1](1, 2) is 1 * 2 = 2. 3 ** 2 = 9." + } + ] + }, + { + "snippet_id": "item:ks-58858d6d96", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "ks-58858d6d96", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Lambda functions\nAnonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.\nLambda basics\nadd_two = lambda x, y: x + y\nprint(add_two(1, 2)) # 3\n# Equivalent to:\ndef add_two(x, " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q17", + "question_id": "sample-final-plus-answers-q17", + "exam_id": "sample-final-plus-answers", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "Empty-sequence equality chain", + "question": "You have the following function called main:\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat will be printed by the following lines:\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))", + "options": { + "a": "True\nFalse\nFalse", + "b": "False\nFalse\nTrue", + "c": "True\nFalse\nTrue", + "d": "True\nTrue\nTrue" + }, + "correct": "d", + "explanation": "The first call builds [True, True, True], the second call builds [False, False, False], and the third call also builds [False, False, False]. In all three cases the chained equality compares three identical booleans, so each printed result is True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nprint(main([{}, {}, {}]))\nprint(main([[1], [2, 2], [3, 3, 3]]))\nprint(main([[1], [2], [3]]))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "This snippet uses an identical structural pattern: a function taking a list, iterating through it, checking a condition, and appending results to a new list 'y' before returning. It helps the student map the logic of the question's 'main' function." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "This snippet uses an identical structural pattern: a function taking a list, iterating through it, checking a condition, and appending results to a new list 'y' before returning. It helps the student map the logic of the question's 'main' function." + }, + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "rationale": "Helps students understand how boolean variables (True/False) interact within conditions and what results from evaluating logical chains." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Lists and Sets' piece provides context on collection equality, which reinforces the concept of comparing sequences." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "This snippet uses an identical structural pattern: a function taking a list, iterating through it, checking a condition, and appending results to a new list 'y' before returning. It helps the student map the logic of the question's 'main' function.", + "critical_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "rationale": "Helps students understand how boolean variables (True/False) interact within conditions and what results from evaluating logical chains.", + "critical_piece_ids": [ + "exam-midterm_2024-1-w3-return-behavior" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Lists and Sets' piece provides context on collection equality, which reinforces the concept of comparing sequences.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-1-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the structural pattern is matched by the best snippet, no snippet explicitly defines the behavior of len() on an empty dictionary {} or an empty list [], nor does it explain Python's chained equality (a == b == c). A student might guess len({}) is 0, but it isn't explicitly provided.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing explicit definitions for the len() function on various empty collections and the behavior of chained comparison operators.", + "missing_concepts": [ + "len() results for empty dicts and lists", + "chained equality (a == b == c) evaluation" + ], + "proposed_fix": "Add a piece to a 'Working with Values' or 'Built-in Functions' snippet explaining that len() returns 0 for {}, [], and \"\", and that a == b == c checks if all three are equal." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "aiq-4", + "proposal": "Add a new bullet point to the 'Working With Values' or 'Lists and Sets' section: 'Empty sequences: len([]) == 0, len({}) == 0, len(\"\") == 0. Chained equality: a == b == c is True only if all three values are equal.'", + "why_helpful": "This directly addresses the two mechanics required to solve the question that are not currently covered by past exam examples.", + "why_maybe_unnecessary": "Some students may find chained equality intuitive, but the len({}) vs len([]) distinction is critical for confidence.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:27:08Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q18", + "question_id": "sample-final-plus-answers-q18", + "exam_id": "sample-final-plus-answers", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "List chunking into sublists", + "question": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nFor example:\nIf you have the original list x as:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nHow do you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:(i + 3)] for i in range(0, 7, 3)]", + "b": "y = [x[i[0]::3] for i in enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of above works" + }, + "correct": "a", + "explanation": "Option A slices the list in chunks of length 3 starting at indices 0, 3, and 6, which produces the three required sublists in order.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-3", + "rationale": "This snippet provides a clear, manual expansion of the range(start, stop, step) function, which is the most critical logic for determining that range(0, 7, 3) produces the indices 0, 3, and 6." + }, + "top_three_snippets": [ + { + "item_id": "aiq-3", + "rationale": "This snippet provides a clear, manual expansion of the range(start, stop, step) function, which is the most critical logic for determining that range(0, 7, 3) produces the indices 0, 3, and 6." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of list slicing syntax ([1::2]), helping a student understand how square brackets and colons are used to subset sequences." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-3", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "This piece is the exact same question, providing both the correct option and a detailed explanation of how range(0, 7, 3) generates the start indices for the chunks." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-3", + "rationale": "This snippet provides a clear, manual expansion of the range(start, stop, step) function, which is the most critical logic for determining that range(0, 7, 3) produces the indices 0, 3, and 6.", + "critical_piece_ids": [ + "aiq-3" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of list slicing syntax ([1::2]), helping a student understand how square brackets and colons are used to subset sequences.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-3", + "rationale": "", + "needed_piece_ids": [ + "aiq-3" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question and answer are present in the snippets. Furthermore, general snippets covering range() and slicing syntax provide enough information to verify the correct option even if the identical question were missing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover the exact question. Without the exact question, the student would need to combine knowledge of range() and slicing. A very explicit explanation of 'Slice with Start:Stop' would strengthen the general case.", + "missing_concepts": [ + "Explicit list slicing syntax for [start:stop] notation" + ], + "proposed_fix": "Add a snippet explicitly showing that list[a:b] takes elements from index a up to (but not including) index b." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:27:30Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-18-w2-conditions", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nA\nB\nC\nD\nA\nOption A uses range(0, 7, 3) which generates 0, 3, 6. The slices x[0:3], x[3:6], and x[6:9] correctly partition the list." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. C" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q19", + "question_id": "sample-final-plus-answers-q19", + "exam_id": "sample-final-plus-answers", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary running totals", + "question": "You have to write a function called main that accepts a dictionary as an input argument.\nBoth the keys and the values of the input are integers.\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary whose keys are smaller than or equal to the output key in question.\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "b": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "c": "Both of the above work as intended", + "d": "None of the above works as intended" + }, + "correct": "c", + "explanation": "The first program computes each output value by summing all input values whose keys are less than or equal to the current key. The second program accumulates values in ascending key order, which yields the same running totals for each key.", + "code_context": "main({5: 1, 2: 5, 4: 2})\n# expected result:\n# {5: 8, 2: 5, 4: 7}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet shows the fundamental pattern of building a new dictionary by iterating over a collection and assigning values to keys (e.g., word_lengths[word] = ...), which is central to both programs provided in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet shows the fundamental pattern of building a new dictionary by iterating over a collection and assigning values to keys (e.g., word_lengths[word] = ...), which is central to both programs provided in the question." + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Demonstrates the concept of summing values within a function, which helps understand the goal of calculating a total (sum of values)." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary usage for retrieving values, which is necessary for understanding the lookup logic in both programs." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Dictionary creation pattern." + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Summation concept." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet shows the fundamental pattern of building a new dictionary by iterating over a collection and assigning values to keys (e.g., word_lengths[word] = ...), which is central to both programs provided in the question.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Demonstrates the concept of summing values within a function, which helps understand the goal of calculating a total (sum of values).", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary usage for retrieving values, which is necessary for understanding the lookup logic in both programs.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Dictionary creation pattern.", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Summation concept.", + "needed_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "While basic dictionary creation is covered, the snippets completely lack coverage of 'sorted()', dictionary '.items()' iteration, and the specific syntax of list comprehensions with conditional filtering ('[v for k, v in d.items() if k <= ...]'). A student with zero knowledge would not be able to deduce that 'sorted(d1.keys())' or the list comprehension work as intended.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets do not cover the advanced dictionary iteration and sorting techniques used in the exam question.", + "missing_concepts": [ + "sorted() function for dictionary keys", + "dictionary .items() method", + "list comprehensions with conditional filtering (if clause)", + "running total/accumulation logic across iterations" + ], + "proposed_fix": "Add a snippet family that demonstrates iterating over sorted dictionary keys and another showing a list comprehension that filters dictionary items." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing: 'for key in sorted(my_dict.keys()): ...' and 'running_total += my_dict[key]'.", + "why_helpful": "Directly maps to program (b) in the question, showing how to process keys in order and accumulate values.", + "why_maybe_unnecessary": "None; this is a core missing concept for this specific problem type.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet showing a list comprehension that sums values based on a key condition: 'total = sum([v for k, v in d.items() if k < limit])'.", + "why_helpful": "Directly maps to program (a), explaining the syntax and behavior of conditional list comprehensions on dictionaries.", + "why_maybe_unnecessary": "None; this is highly specific and not covered elsewhere.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:27:57Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q20", + "question_id": "sample-final-plus-answers-q20", + "exam_id": "sample-final-plus-answers", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary equality with zip and enumerate", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) produces key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same key-value pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-65c4de2e9d", + "rationale": "This is the most relevant general snippet as it explains dictionary equality behavior ({1:1,2:2}=={2:2,1:1} is True), which is necessary to understand the final print statement." + }, + "top_three_snippets": [ + { + "item_id": "ks-65c4de2e9d", + "rationale": "This is the most relevant general snippet as it explains dictionary equality behavior ({1:1,2:2}=={2:2,1:1} is True), which is necessary to understand the final print statement." + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary structure and how keys/values are represented, helping a beginner visualize the result of the loops." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Provides additional context on dictionary iteration, which helps clarify how the variables 'key' and 'value' might be assigned in the loops." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-65c4de2e9d", + "rationale": "" + }, + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "This past exam piece is near-identical to the question, explicitly comparing dictionaries created via zip and enumerate and stating they result in the same dictionary: {1: 2, 2: 3, 3: 4, 4: 5}." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-65c4de2e9d", + "rationale": "This is the most relevant general snippet as it explains dictionary equality behavior ({1:1,2:2}=={2:2,1:1} is True), which is necessary to understand the final print statement.", + "critical_piece_ids": [ + "ks-65c4de2e9d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows basic dictionary structure and how keys/values are represented, helping a beginner visualize the result of the loops.", + "critical_piece_ids": [ + "exam-trial_midterm-10-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Provides additional context on dictionary iteration, which helps clarify how the variables 'key' and 'value' might be assigned in the loops.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-65c4de2e9d", + "rationale": "", + "needed_piece_ids": [ + "ks-65c4de2e9d" + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial_midterm-10-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The near-identical past exam piece provides the direct answer. However, if that piece were missing, the general snippets fail to define zip() or enumerate(), which are the fundamental concepts needed to solve the problem from scratch.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate set lacks any general (non-exam) definition of the zip() and enumerate() built-in functions.", + "missing_concepts": [ + "zip() function pairing mechanics", + "enumerate() function with optional start parameter" + ], + "proposed_fix": "Add a lecture-style snippet explaining how zip(list1, list2) pairs corresponding elements and how enumerate(list, start) generates pairs of (index, element) starting from a specific number." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: Iteration Helpers. Snippet: 'zip(l1, l2) creates pairs of elements from two lists. enumerate(l, start=0) creates index-value pairs; for example, enumerate([\"a\"], 1) yields (1, \"a\").'", + "why_helpful": "This provides the specific mechanical knowledge required to trace the code without relying on a past exam question's answer.", + "why_maybe_unnecessary": "The information is technically 'covered' by the near-identical exam piece, but not in a way that teaches the student the underlying rule.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:28:30Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:ks-65c4de2e9d", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "ks-65c4de2e9d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Dictionaries\nSets of key:value pairs. Keys must be unique and immutable (hashable). Dictionaries are unordered for equality ({1:1,2:2}=={2:2,1:1} is True). Cannot be sorted. You can check membership with 'in' — this checks KEYS only. Keys() gives key sequence, values() gives valu" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?\nA\nB\nC\nD\nA\nBoth d1 and d2 result in the same dictionary: {1: 2, 2: 3, 3: 4, 4: 5}." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-24-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-24-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA The code will result in an error.\nB True\nC None\nD False\nEnd of test Trial Midterm - Introduction to Pyth" + } + ] + }, + { + "snippet_id": "item:ks-ab66f3bab6", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "ks-ab66f3bab6", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Methods vs functions\nMethods are functions attached to objects. Calling obj.method() is equivalent to Class.method(obj). For mutable objects: some methods CHANGE the object (e.g. list.sort()), some RETURN a value (e.g. list.index()). For immutable objects: methods always return a" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q21", + "question_id": "sample-final-plus-answers-q21", + "exam_id": "sample-final-plus-answers", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "Dictionary iteration semantics", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not (key, value) pairs, so `for key, value in d1:` is invalid. The other three variants all sum the dictionary values correctly.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "Although it does not explain iteration syntax, it involves logic regarding dictionary keys and values, providing some context on how they are used together." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "Although it does not explain iteration syntax, it involves logic regarding dictionary keys and values, providing some context on how they are used together." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Shows a dictionary comprehension, illustrating the relationship between keys (elements) and values (lengths)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "Matches the question text exactly and explicitly states the rule that iterating directly over a dictionary yields only keys, causing a ValueError if unpacked into two variables." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "rationale": "Although it does not explain iteration syntax, it involves logic regarding dictionary keys and values, providing some context on how they are used together.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "Shows a dictionary comprehension, illustrating the relationship between keys (elements) and values (lengths).", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam question provides both the scenario and the specific technical explanation required to identify option 'a' as incorrect.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The knowledge base relies entirely on an identical past exam question rather than general conceptual snippets.", + "missing_concepts": [ + "Explicit explanation of .keys(), .values(), and .items() methods for dictionary iteration.", + "General rule that 'for x in dict:' iterates over keys only." + ], + "proposed_fix": "Add a foundational snippet covering dictionary traversal methods and common iteration pitfalls (like the unpacking error shown in this question)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Iteration & Methods' summary snippet that explains: 1. dict.keys(), 2. dict.values(), 3. dict.items() (and how to unpack them), 4. Default iteration behavior (keys only).", + "why_helpful": "This would allow students to solve the problem by applying a general rule rather than just finding a matching past question.", + "why_maybe_unnecessary": "The identical exam piece already exists, which 'solves' it for this specific exam prep context.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:29:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?\nA\nB\nC\nD\nA\nThis is a standard dictionary comprehension. Option B is a list comprehension, Option C is a se" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?\nA\nB\nC\nD\nC\nBoth methods correctly calculate the cumulative sums based on key values, though Option B is more efficient." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q22", + "question_id": "sample-final-plus-answers-q22", + "exam_id": "sample-final-plus-answers", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "String count method", + "question": "You have the following string\nx = 'Amsterdam'\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method `count` must be called on the string object itself. `x.count('a')` returns 1 for the lowercase 'a' in 'Amsterdam'.", + "code_context": "x = 'Amsterdam'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "While it implements a manual loop rather than the method, it focuses on the logic of counting a specific character within a list of strings, which is the closest thematic match among non-identical snippets." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "While it implements a manual loop rather than the method, it focuses on the logic of counting a specific character within a list of strings, which is the closest thematic match among non-identical snippets." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Helpful for understanding that 'A' and 'a' are distinct (case sensitivity), which explains why the count for 'a' in 'Amsterdam' is 1." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions that methods (like .map()) are applied to objects, which supports the concept of dot notation for string methods." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "This is almost exactly the same question and explicitly explains that count() is a string method called with dot notation, providing the direct answer." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "While it implements a manual loop rather than the method, it focuses on the logic of counting a specific character within a list of strings, which is the closest thematic match among non-identical snippets.", + "critical_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Helpful for understanding that 'A' and 'a' are distinct (case sensitivity), which explains why the count for 'a' in 'Amsterdam' is 1.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Mentions that methods (like .map()) are applied to objects, which supports the concept of dot notation for string methods.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One candidate snippet is a near-identical past exam question that provides both the correct answer and the underlying principle (dot notation for string methods).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets rely heavily on a past exam question that is identical. There is no general documentation snippet explaining the string 'count' method or the general syntax for string methods vs standalone functions.", + "missing_concepts": [ + "General str.count() syntax", + "Dot notation for string methods versus standalone functions" + ], + "proposed_fix": "Add a conceptual snippet explaining string methods with examples of .count(), .upper(), and .lower() showing dot notation syntax." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Methods - Count. Description: The .count() method returns the number of times a specified value appears in a string. Syntax: string.count(value). Example: 'banana'.count('a') returns 3. Note: Methods are called ON the object using a dot, unlike standalone functions.", + "why_helpful": "Provides the general rule for the count method without relying on a student finding an identical exam question.", + "why_maybe_unnecessary": "The near-identical piece already exists, but a general rule is better for long-term learning.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:29:41Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-22-w2-conditions", + "snippet_label": "String Operations and Methods", + "week": 4, + "topic": "String Operations and Methods", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?\nA\nB\nC\nD\nB\nThe count() method is a string method, not a standalone function. It is called using the dot notation on a string object." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q23", + "question_id": "sample-final-plus-answers-q23", + "exam_id": "sample-final-plus-answers", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "Higher-order function returning 30", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "The first call returns (1+5)+(2+5)+(3+5)+(4+5)=30, and the second returns 1^2+2^2+3^2+4^2=30. Both produce the requested result.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains the use of *args to accept a flexible number of arguments and perform an operation on them, which is the core structural pattern of the 'calculation' function." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains the use of *args to accept a flexible number of arguments and perform an operation on them, which is the core structural pattern of the 'calculation' function." + }, + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "rationale": "Provides a clear example of the 'for num in args' loop syntax which matches the 'for el in args' pattern in the question." + }, + { + "item_id": "aiq-3", + "rationale": "Mentions applying a lambda/function to elements in an iterable, helping bridge the gap for higher-order function usage." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "snippet_id": "item:exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "This piece contains the exact same logic and calculations (6+7+8+9=30 and 1+4+9+16=30) as the question being evaluated." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "Explains the use of *args to accept a flexible number of arguments and perform an operation on them, which is the core structural pattern of the 'calculation' function.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "rationale": "Provides a clear example of the 'for num in args' loop syntax which matches the 'for el in args' pattern in the question.", + "critical_piece_ids": [ + "exam-midterm_2024-14-w3-arguments" + ] + }, + { + "snippet_id": "item:aiq-3", + "rationale": "Mentions applying a lambda/function to elements in an iterable, helping bridge the gap for higher-order function usage.", + "critical_piece_ids": [ + "aiq-3" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The near-identical past exam piece provides the answer directly. Even without it, the structural snippets for *args and loops provide enough context to trace the arithmetic.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is provided by the near-identical piece, a student with zero knowledge might struggle to understand the 'lambda x: x + 5' syntax without that direct hint.", + "missing_concepts": [ + "lambda function syntax (lambda arguments: expression)" + ], + "proposed_fix": "Add a snippet specifically defining lambda functions as 'short, one-line functions' with an example of how 'lambda x: x + 5' maps an input to an output." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: Lambda Basics. Content: 'A lambda function is a small anonymous function. Syntax: lambda arguments : expression. For example, lambda x : x + 10 takes x and returns x + 10. In a loop, if you pass this to a function, it executes the math for every item.'", + "why_helpful": "It clarifies the 'lambda' keyword which is the only cryptic part of the options for a non-programmer.", + "why_maybe_unnecessary": "The near-identical exam piece already demonstrates the calculation result for the specific lambdas used in the question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:29:59Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. C" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-23-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Which of the following function calls would return the number 30 as a result?\nA\nB\nC\nD\nC\nThe first call sums (6+7+8+9)=30. The second call sums (1+4+9+16)=30." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:sample-final-plus-answers-q24", + "question_id": "sample-final-plus-answers-q24", + "exam_id": "sample-final-plus-answers", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "Circle area imports and aliases", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C aliases the module as `constants`, so `math.pi` is not defined there. The other three options reference pi correctly.", + "code_context": "# area formula\n# pi * r ** 2" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "While it doesn't cover imports, it demonstrates the exponentiation operator (**2) used in the area formula (pi * r ** 2)." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "While it doesn't cover imports, it demonstrates the exponentiation operator (**2) used in the area formula (pi * r ** 2)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This piece contains the exact same question and explicitly explains that aliasing a module (e.g., 'import math as constants') makes the original name ('math') unavailable." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "While it doesn't cover imports, it demonstrates the exponentiation operator (**2) used in the area formula (pi * r ** 2).", + "critical_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the near-identical past exam piece, there are no snippets explaining how 'import', 'from ... import', or 'as' aliases affect the available namespace in Python.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets lack any general explanation of Python's import system and aliasing mechanics.", + "missing_concepts": [ + "Module aliasing (import X as Y)", + "Namespace availability after aliasing", + "From ... import syntax" + ], + "proposed_fix": "Add a foundational snippet or lecture summary covering the different ways to import modules and their effects on the local namespace." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Python Import and Alias Reference. Content: 1. 'import math' -> use 'math.pi'. 2. 'import math as m' -> use 'm.pi' ('math' becomes undefined). 3. 'from math import pi' -> use 'pi' directly. 4. 'from math import pi as p' -> use 'p' ('pi' becomes undefined).", + "why_helpful": "This provides the necessary theoretical background to distinguish between the correct and incorrect aliasing in the options without relying on seeing the exact exam question before.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:30:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Which script does NOT print the correct answer for the area of a circle?\nA\nB\nC\nD\nC\nIf math is imported as constants, it must be referred to as 'constants.pi'. 'math.pi' will no longer be available unless 'math' was also imported directly." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Corre" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q01", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q01", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "6-OOP-1", + "question": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor, then the \"mode\" attribute should be equal to \"land\".\n\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "b": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode):\n self.name = vehicle_name\n self.mode = vehicle_mode", + "c": "class Vehicle:\n def __init__(self, vehicle_name, vehicle_mode=\"land\"):\n return name, mode", + "d": "class Vehicle:\n def __init__(vehicle_name, vehicle_mode):\n name = vehicle_name\n mode = vehicle_mode" + }, + "correct": "a", + "explanation": "Option A defines an initializer with a required vehicle name and a default mode of \"land\", then stores both on the instance using self.", + "code_context": "my_car = Vehicle(\"Mazda\")\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "This family contains a piece on 'Mutable default argument' (def f(lst=[])) which demonstrates the syntax for default values in Python, directly helping with the 'mode=\"land\"' part of the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "This family contains a piece on 'Mutable default argument' (def f(lst=[])) which demonstrates the syntax for default values in Python, directly helping with the 'mode=\"land\"' part of the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Provides context for OOP and methods, though it lacks the critical syntax for class initialization." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece contains the exact text of the current question, including the Vehicle class requirements." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "rationale": "This is another identical version of the same question from a different exam source." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "This family contains a piece on 'Mutable default argument' (def f(lst=[])) which demonstrates the syntax for default values in Python, directly helping with the 'mode=\"land\"' part of the question.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Provides context for OOP and methods, though it lacks the critical syntax for class initialization.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the student can 'cheat' using identical past exam questions, the general snippets do not explain how to define a class, the purpose of __init__, or why 'self' is required in the argument list and for attribute assignment. A zero-knowledge student would not understand why Option A is correct over Option D (missing self) or Option C (using return).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a foundational explanation of Python class syntax, specifically the constructor method and instance attribute assignment.", + "missing_concepts": [ + "Class definition (class Name:)", + "The __init__ method (constructor)", + "The self parameter in methods", + "Instance attribute assignment (self.attribute = value)" + ], + "proposed_fix": "Add a conceptual snippet explaining the structure of a Python class and its __init__ method." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet 'OOP: Class Initialization' covering: 1. How to define a class; 2. The __init__(self, ...) syntax; 3. Why self is needed to store attributes; 4. Default argument syntax within __init__.", + "why_helpful": "It would allow a student to logically choose the correct option (A) by identifying the correct constructor structure and default value syntax, rather than relying on identical question matches.", + "why_maybe_unnecessary": "If the cheat sheet's goal is primarily to provide a searchable database of past questions, the existing identical pieces already provide the answer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:30:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q02", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q02", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "6-OOP-2", + "question": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will the following command print to the screen?\nprint(book_1.show_rating())", + "options": { + "a": "3.7", + "b": "4", + "c": "None", + "d": "3.67" + }, + "correct": "a", + "explanation": "The reviews are 5, 3, and 3, so the average is 11 / 3 = 3.666..., which show_rating rounds to one decimal place, giving 3.7.", + "code_context": "class Book:\n def __init__(self, title, author, review_scores=None):\n self.title = title\n self.author = author\n self.review_scores = review_scores if review_scores else []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def show_rating(self):\n if self.review_scores:\n return round(sum(self.review_scores) / len(self.review_scores), 1)\n\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\nprint(book_1.show_rating())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-state-compare", + "rationale": "Directly mirrors the question's logic for state tracking (appending to a list) and explains constructor default patterns for list attributes." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "Directly mirrors the question's logic for state tracking (appending to a list) and explains constructor default patterns for list attributes." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides a clean example of an __init__ method initializing multiple attributes from constructor arguments." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Reinforces the concept of calculating an average review score within a Book class context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-state-compare", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "This piece contains the exact same question text, class definition, and method calls as the current question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "rationale": "This piece contains the exact same scenario and question text about the Book class and add_review method." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "Directly mirrors the question's logic for state tracking (appending to a list) and explains constructor default patterns for list attributes.", + "critical_piece_ids": [ + "manual-oop-state-compare", + "manual-oop-init-defaults" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides a clean example of an __init__ method initializing multiple attributes from constructor arguments.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Reinforces the concept of calculating an average review score within a Book class context.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "", + "needed_piece_ids": [ + "manual-oop-state-compare", + "manual-oop-init-defaults" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The provided AI examples in the 'core' family show the exact pattern of using a list to store scores via an add_review method, making the state trace straightforward.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets explain how self-state works and how lists are updated, but they do not explicitly demonstrate the built-in round() function's behavior.", + "missing_concepts": [ + "round() function behavior" + ], + "proposed_fix": "Add a small code snippet or key point showing how round(x, n) works, specifically rounding to 1 decimal place." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating round(): `val = 11/3 # 3.666...; print(round(val, 1)) # Output: 3.7`.", + "why_helpful": "Confirms the final step of the calculation which distinguishes option (a) from (d).", + "why_maybe_unnecessary": "Most students intuitively understand that rounding 3.66 to one decimal place yields 3.7.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:31:18Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book" + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-oop-state-compare", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.sc" + }, + { + "item_id": "manual-oop-compare-none-case", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Return `None` when neither object clearly wins\nclass Book:\n def __init__(self, title, scores):\n self.title = title\n self.scores = scores\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def winner_against(self, other):\n if se" + }, + { + "item_id": "manual-oop-init-defaults", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state " + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + }, + { + "item_id": "kp-manual-self-attr", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Use `self.attr = ...` to store per-object state. A bare assignment like `attr = ...` inside a method only creates or updates a local variable." + }, + { + "item_id": "manual-oop-attrs", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Class attribute vs instance attribute\nclass Rectangle:\n units = 'cm'\n\n def __init__(self, width):\n self.width = width\n\nr1 = Rectangle(3)\nr2 = Rectangle(5)\nr2.units = 'm'\nprint(r1.units, r2.units)\n`self.width` is per object; `Class.units` is shared until an instance s" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-22-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-22-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q03", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q03", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "6-strings-1", + "question": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\n\nFor example, if:\nstudents = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 7.5.\nBernard has received a grade of 8.0.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "for student in students:\n print(f\"{student['Name']} has received a grade of {student['Grade']:.1f}.\")", + "b": "for student, grade in students.items():\n print(f\"{student} has received a grade of {grade:.1f}.\")", + "c": "for student in students:\n print(f\"{student[\\\"Name\\\"]} has received a grade of {student[\\\"Grade\\\"]:.1f}.\")", + "d": "for student, grade in students:\n print(f\"{student} has received a grade of {grade:.1f}.\")" + }, + "correct": "a", + "explanation": "Option A iterates through each dictionary in the list and formats the student's name and grade correctly to one decimal place. The other options use the wrong iteration pattern or invalid access pattern for this data structure.", + "code_context": "students = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a clear example of mapping two lists into a dictionary and implies dictionary key-value structure, which helps understand how to access data within the 'students' list." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a clear example of mapping two lists into a dictionary and implies dictionary key-value structure, which helps understand how to access data within the 'students' list." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary literal and how keys (months) map to values (sales), helping a student visualize the 'students' data structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "This is the exact same question (list of dictionaries 'students' with 'Name' and 'Grade' keys) from a previous trial exam." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "This is a near-identical version of the same question from the 24/25 sample final." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a clear example of mapping two lists into a dictionary and implies dictionary key-value structure, which helps understand how to access data within the 'students' list.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary literal and how keys (months) map to values (sales), helping a student visualize the 'students' data structure.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the past exam snippets. Even without the direct match, the candidate snippets explain dictionary structures, though they lack a specific example of f-string float formatting (.1f).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the past exam snippets provide the answer directly, a general snippet explaining f-string formatting (specifically float precision like :.1f) and iterating over a list of dictionaries is missing.", + "missing_concepts": [ + "f-string float precision formatting (:.1f)", + "iterating over a list of dictionaries" + ], + "proposed_fix": "Add a snippet demonstrating f-string syntax for rounding floats and accessing dictionary values inside a loop." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Formatting and List Iteration. Content: To iterate over a list of dictionaries: 'for item in my_list: print(item[\"key\"])'. To format a float to 1 decimal place: 'f\"{value:.1f}\"'.", + "why_helpful": "Directly explains the syntax required for the 'correct' option (a) and helps distinguish it from the 'items()' dict method used incorrectly in option (b).", + "why_maybe_unnecessary": "The student can find the answer by looking at the identical past exam item.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:31:30Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q04", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q04", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "6-strings-2", + "question": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character, at various places).\n\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "def format_phone_number(number):\n number.replace(\"-\", \"\")\n return number", + "b": "def format_phone_number(number):\n return number.replace(\"-\", \"\")", + "c": "def format_phone_number(number):\n digits = []\n for char in number:\n if char in \"0123456789\":\n digits.append(char)\n return \"\".join(digits)", + "d": "def format_phone_number(number):\n return \"\".join(number.split(\"-\"))" + }, + "correct": "a", + "explanation": "Option A does not work because strings are immutable and number.replace(\"-\", \"\") returns a new string that is ignored. The function then returns the original unmodified number.", + "code_context": "format_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\n# all should return \"0205251400\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "This family contains a critical conceptual piece about string immutability/slicing which explains why Option A fails." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "This family contains a critical conceptual piece about string immutability/slicing which explains why Option A fails." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides an example of a function extracting substrings (get_tld), which helps understand the logic of the correct options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "aiq-5", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This is the exact same question (formatting phone numbers) from a trial final exam." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-5", + "rationale": "This family contains a critical conceptual piece about string immutability/slicing which explains why Option A fails.", + "critical_piece_ids": [ + "aiq-5" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides an example of a function extracting substrings (get_tld), which helps understand the logic of the correct options.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question exists in the past exam snippets, and the AI summary piece (aiq-5) explicitly mentions that slicing/string operations create NEW objects, which is the core of the 'Option A' error (immutability).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the answer is present, the specific concept of string immutability (that .replace() doesn't change the original variable) could be more explicitly highlighted in a general-purpose snippet.", + "missing_concepts": [ + "string immutability", + "inplace vs return values for string methods" + ], + "proposed_fix": "Add a snippet specifically explaining that string methods like .replace(), .strip(), and .upper() return a new string and do not modify the original variable." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Immutability and Methods. Content: Strings in Python are immutable. Methods like `s.replace('a', 'b')` or `s.strip()` return a NEW string. If you don't assign it (e.g., `s = s.replace(...)`), the change is lost. Example: `def fix(s): s.replace('-', ''); return s` returns the original string unchanged.", + "why_helpful": "This directly explains the 'trap' in Option A which is a common exam pattern.", + "why_maybe_unnecessary": "The information is partially covered in the 'Slicing creates a NEW object' note in aiq-5.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:31:42Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q05", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q05", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-new_column-1", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] + df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x + df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\" + \"B\"]", + "d": "df[\"C\"] = df[\"A\" + \"B\"]" + }, + "correct": "a", + "explanation": "Option A performs elementwise addition between columns A and B and stores the result in column C. The other options either misuse map, index into the columns object incorrectly, or look for a non-existent combined column name.", + "code_context": "df has numeric columns \"A\" and \"B\"; column \"C\" should contain their sum." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This is the most relevant non-identical snippet as it discusses performing mathematical operations (square of difference) on a Pandas Series, illustrating the concept of element-wise/vectorized operations." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This is the most relevant non-identical snippet as it discusses performing mathematical operations (square of difference) on a Pandas Series, illustrating the concept of element-wise/vectorized operations." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a printed Pandas DataFrame with columns A, B, C, and D, which helps the student visualize the data structure being discussed." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This piece contains the exact same question text, topic, and scenario as the target question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "This is a near-identical version of the question from a different year, including partial explanation text about vectorized addition." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This is the most relevant non-identical snippet as it discusses performing mathematical operations (square of difference) on a Pandas Series, illustrating the concept of element-wise/vectorized operations.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a printed Pandas DataFrame with columns A, B, C, and D, which helps the student visualize the data structure being discussed.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the near-identical pieces provide the answer directly, the remaining snippets do not explicitly show the syntax for creating a new column by adding two existing columns (df['C'] = df['A'] + df['B']). A student with zero prior knowledge would not be able to deduce the specific assignment syntax from the provided context.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate list lacks a general-purpose reference or lecture snippet explaining Pandas arithmetic and column creation.", + "missing_concepts": [ + "Pandas vectorized column addition syntax", + "Creating/Assigning a new column in a DataFrame" + ], + "proposed_fix": "Add a snippet from Week 5 lecture materials that explicitly covers 'Vectorized Operations' and 'Adding New Columns'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet 'Pandas Column Arithmetic' that shows: df['new_col'] = df['col_1'] + df['col_2']. Include a brief note that this is a vectorized operation that adds values row-by-row.", + "why_helpful": "This would provide a logical basis for choosing Option A without relying on the student having seen the exact same exam question previously.", + "why_maybe_unnecessary": "It is only unnecessary if we assume the student will always have access to near-identical past exam questions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:32:08Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q06", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q06", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-selection-1", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that only contains those elements of column \"B\" in df that have an even-numbered index. Which of the following code lines will achieve what you want?", + "options": { + "a": "df.loc[df.index % 2 == 0, [\"B\"]]", + "b": "df[2, 4, 6, \"B\"]", + "c": "df.iloc[[2, 4, 6], 2]", + "d": "df.loc[2::2, \"B\"]" + }, + "correct": "a", + "explanation": "Option A filters rows whose index is even and selects column B while keeping the result as a DataFrame by using [[\"B\"]]. Option D would return a Series, not a DataFrame, and the other options do not select the requested data correctly.", + "code_context": "df printed as:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "While it focuses on column creation/addition, it is the only remaining snippet that demonstrates basic pandas DataFrame column indexing syntax (df['A'])." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "While it focuses on column creation/addition, it is the only remaining snippet that demonstrates basic pandas DataFrame column indexing syntax (df['A'])." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces basic pandas column operations and vectorized addition logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This piece contains the exact DataFrame and the first part of the question text." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This piece describes the logic of selecting column 'B' for even indices and explains why using a list ['B'] returns a DataFrame." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "While it focuses on column creation/addition, it is the only remaining snippet that demonstrates basic pandas DataFrame column indexing syntax (df['A']).", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Reinforces basic pandas column operations and vectorized addition logic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the near-identical exam items, there are no snippets explaining .loc, .iloc, boolean indexing on indices, or the distinction between returning a Series vs. a DataFrame (the list-in-brackets syntax).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current selection lacks any general documentation or lecture-based explanation of pandas selection methods (.loc vs .iloc) and the syntactical difference between single-label and list-of-labels selection.", + "missing_concepts": [ + "pandas .loc for label-based selection", + "Boolean indexing on DataFrame indices", + "Series vs DataFrame return types in column selection (['Col'] vs [['Col']])", + "The modulo operator (%) used for even/odd filtering" + ], + "proposed_fix": "Add a general lecture-based snippet from Week 5 covering .loc, boolean indexing, and selection result types." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet 'Pandas Selection and Filtering' from Week 5 materials. Include: 1) Example of df.loc[boolean_condition, ['ColName']] to return a DataFrame. 2) Explanation that df.loc[..., 'ColName'] returns a Series. 3) Usage of df.index % 2 == 0 to filter even indices.", + "why_helpful": "This would allow a student to solve the problem using general principles rather than relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "The near-identical pieces already provide the answer, but they don't support general learning.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:32:31Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q07", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q07", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-sorting-1", + "question": "There are two pandas DataFrames: df1 and df2. They look like this, when printed:\n\nprint(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3\n\nWhich of the following code lines could not have created df2 from df1?", + "options": { + "a": "df2 = df1.sort_index(ascending=False)[[\"A\", \"C\", \"D\"]]", + "b": "df2 = df1.iloc[[3, 2, 1], [0, 2, 3]]", + "c": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"D\", ascending=False)", + "d": "df2 = df1.loc[2:4, [\"A\", \"C\", \"D\"]].sort_values(\"C\")" + }, + "correct": "a", + "explanation": "Option A sorts the entire DataFrame by index in descending order and would include rows 5 and 1 as well, so it would not match df2. The other options all produce rows 4, 3, and 2 with columns A, C, and D.", + "code_context": "print(df1)\n\n A B C D\n1 5.0 8.2 9.5 4.4\n2 6.0 2.4 9.1 3.3\n3 3.2 5.2 8.9 3.6\n4 7.8 8.7 7.9 8.0\n5 1.2 9.7 2.9 3.0\n\nprint(df2)\n\n A C D\n4 7.8 7.9 8.0\n3 3.2 8.9 3.6\n2 6.0 9.1 3.3" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet deals with the high-level concept of creating new DataFrames from existing ones in Pandas, which is the core action of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet deals with the high-level concept of creating new DataFrames from existing ones in Pandas, which is the core action of the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides additional context on basic Pandas DataFrame operations (column manipulation)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "This snippet is a verbatim match for the current question, including the identical DataFrame values and the explanation for why Option A is incorrect." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet deals with the high-level concept of creating new DataFrames from existing ones in Pandas, which is the core action of the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides additional context on basic Pandas DataFrame operations (column manipulation).", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "One candidate snippet is an exact duplicate of the question and answer. Without that specific piece, the set would be insufficient as it lacks definitions for loc, iloc, sort_index, and sort_values.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The knowledge base relies on a past exam match. There are no technical reference snippets explaining the syntax or behavior of Pandas indexing and sorting methods.", + "missing_concepts": [ + "pandas.DataFrame.loc (inclusive slicing)", + "pandas.DataFrame.iloc (integer-based indexing)", + "pandas.DataFrame.sort_index", + "pandas.DataFrame.sort_values" + ], + "proposed_fix": "Add a technical snippet covering Pandas data selection (loc vs iloc) and sorting (sort_index vs sort_values)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A technical snippet titled 'Pandas: Selecting and Sorting' explaining that .loc[start:stop] is inclusive, .iloc uses 0-based positions, and sort_index/sort_values reorders the entire DataFrame unless sliced.", + "why_helpful": "It would allow a student to solve the logic puzzle using syntax rules rather than relying on having seen the exact question before.", + "why_maybe_unnecessary": "The student might find the exact question in the past exam items.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:32:52Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "Which of the following code lines could NOT have created df2 from df1?\nA\nB\nC\nD\nA\nOption A would sort all 5 rows of df1 and keep columns A, C, D, resulting in a 5-row DataFrame. df2 only has 3 rows (indices 4, 3, 2)." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)\nA\nB\nC\nD\nA\n'3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is False. x == y == z evaluates as (x == y) and (y == z), which is False and True, resulting in False." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q08", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q08", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-string-1", + "question": "There is a pandas Series called s, which contains Dutch municipality and corresponding province names, separated by a semicolon and a whitespace. The following, for example, is an element of this Series: \"Amsterdam; Noord-Holland\".\n\nYou'd like to create a new Series that only contains the municipality names from s in the same order. Which of the following code lines will achieve what you want?", + "options": { + "a": "s.map(lambda x: x.split(\"; \")[0])", + "b": "s.split(\"; \")[0]", + "c": "s.lambda(x.split(\"; \"))", + "d": "s.str[:9]" + }, + "correct": "a", + "explanation": "Option A applies split('; ') to each element in the Series and takes the first part, which is the municipality name. The other options either do not operate elementwise or do not reliably extract the municipality name.", + "code_context": "Example element in s:\n\"Amsterdam; Noord-Holland\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides the closest context regarding creating a new Series from an existing Series 's', though it uses arithmetic rather than string logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides the closest context regarding creating a new Series from an existing Series 's', though it uses arithmetic rather than string logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates the concept of extracting a specific part of a string based on a format (TLD from a URL), which is conceptually similar to extracting the municipality." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the exact same question, covering the same municipality/province data format and identifying .map() as the solution." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Provides the closest context regarding creating a new Series from an existing Series 's', though it uses arithmetic rather than string logic.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates the concept of extracting a specific part of a string based on a format (TLD from a URL), which is conceptually similar to extracting the municipality.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the identical past exam piece, none of the remaining snippets explain the '.map(lambda...)' syntax or the '.str' accessor required to perform element-wise string operations on a pandas Series. A student would not know how to bridge standard string splitting with pandas Series operations.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete lack of general documentation or snippets explaining how to manipulate strings within a pandas Series.", + "missing_concepts": [ + "pandas Series .map() method", + "lambda functions in pandas context", + "pandas Series .str accessors", + "element-wise string splitting in pandas" + ], + "proposed_fix": "Add a general 'Pandas String Operations' snippet that explains the '.str' accessor (e.g., s.str.split().str[0]) and the '.map(lambda x: ...)' pattern for custom transformations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Pandas String Manipulation. Content: To process strings in a Series 's', use 's.str' for vectorized methods like 's.str.split(\"; \").str[0]' or 's.map(lambda x: ...)' to apply a function to every element.", + "why_helpful": "This would provide the necessary syntax knowledge for students to identify why option (a) is correct and why (b) fails (missing .str or .map).", + "why_maybe_unnecessary": "Only if we assume students will always have access to the exact past exam question which contains the answer.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:33:47Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q09", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q09", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-1", + "question": "Take a look at the following code segment.\n\nfrom datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]\n\nSuppose that you call the function like this:\nget_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"])\n\nWhat does the function call return?", + "options": { + "a": "[3, None, 2]", + "b": "[2, None, 3]", + "c": "[3, 2]", + "d": "[2, 3]" + }, + "correct": "a", + "explanation": "\"03/02/2013\" matches %m/%d/%Y and gives month 3, \"03.02.2013\" matches neither branch and becomes None, and \"03-02-2013\" matches %d-%m-%Y and gives month 2.", + "code_context": "from datetime import datetime\n\ndef get_months(date_strings):\n dates = []\n for date_str in date_strings:\n if \"-\" in date_str:\n dates.append(datetime.strptime(date_str, \"%d-%m-%Y\"))\n elif \"/\" in date_str:\n dates.append(datetime.strptime(date_str, \"%m/%d/%Y\"))\n else:\n dates.append(None)\n return [date.month if date is not None else None for date in dates]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "This snippet is the best structural match, demonstrating the pattern of iterating through a list, applying conditional logic inside a loop, and appending results to a new list." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "This snippet is the best structural match, demonstrating the pattern of iterating through a list, applying conditional logic inside a loop, and appending results to a new list." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Shows a function taking a string input and performing a check for specific characters (dashes), which helps understand the conditional branches in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "rationale": "This snippet contains the exact same code, function call, and explanation of the date parsing logic for the specific date strings provided." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "rationale": "This snippet is the best structural match, demonstrating the pattern of iterating through a list, applying conditional logic inside a loop, and appending results to a new list.", + "critical_piece_ids": [ + "exam-trial_midterm-6-w2-conditions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Shows a function taking a string input and performing a check for specific characters (dashes), which helps understand the conditional branches in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-trial_midterm-6-w2-conditions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the near-identical past exam piece, there is no information in the library explaining the 'datetime' module, 'strptime' format codes (%d, %m, %Y), or the '.month' attribute. A student with zero prior knowledge could understand the loop and 'if/elif/else' structure, but would have no way to determine what the 'strptime' calls return or what '.month' refers to.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The library relies entirely on a specific past exam question to answer this topic. There are no general concepts covering the 'datetime' library or advanced list comprehension syntax.", + "missing_concepts": [ + "datetime.strptime() function and its behavior", + "Datetime format codes like %d (day), %m (month), %Y (year)", + "Attributes of datetime objects such as .month", + "List comprehension with inline if-else syntax: [x if cond else y for x in list]" + ], + "proposed_fix": "Add a general 'Datetime' snippet covering parsing and attributes, and a 'List Comprehensions' snippet covering conditional logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Datetime' reference snippet: 1. Explain datetime.strptime(str, format). 2. Define common codes: %d=day, %m=month, %Y=year. 3. Show attributes: .day, .month, .year.", + "why_helpful": "Provides the semantic knowledge required to solve any datetime parsing problem, not just this specific exam question.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for 'Conditional List Comprehensions' showing the syntax: [value_if_true if condition else value_if_false for item in iterable].", + "why_helpful": "The return statement in the question uses a complex list comprehension that is not explained by the simpler filtering snippets currently available.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:34:28Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?\nA\nB\nC\nD\nA\n1st string: contains '/' so it uses %m/%d/%Y -> month 3. 2nd: contains neither '-' nor '/' -> None. 3rd: contains '-' so it uses %d-" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q10", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q10", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-2", + "question": "Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366.\n\nFor example, the function call:\nday_of_year(datetime(2022, 2, 1))\nshould return the integer:\n32\n\nWhich of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.)", + "options": { + "a": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", + "b": "def day_of_year(dt):\n return timedelta(dt - datetime(dt.year, 1, 1)) + 1", + "c": "def day_of_year(dt):\n return dt - datetime(dt.year, 1, 1) + 1", + "d": "def day_of_year(dt):\n return (dt - datetime(dt.year, 1, 0)).days" + }, + "correct": "a", + "explanation": "Subtracting January 1 of the same year gives the zero-based offset in days, and adding 1 converts it to the day number within the year. The other options either return or manipulate timedeltas incorrectly or use an invalid date.", + "code_context": "Example target behavior:\nday_of_year(datetime(2022, 2, 1))\n# returns 32" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": null, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Shows basic function definition syntax which matches the required day_of_year(dt) structure, though it lacks the relevant datetime logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This piece contains the exact same question and explanation, explicitly stating that datetime subtraction yields a timedelta, the .days attribute is needed to get an integer, and adding 1 is required for the day number." + } + ], + "best_snippet_family": {}, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Shows basic function definition syntax which matches the required day_of_year(dt) structure, though it lacks the relevant datetime logic.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "Excluding the identical exam piece, the current snippets offer no guidance on datetime arithmetic, resulting types (timedelta), or why integer addition to a timedelta fails. A student without prior knowledge cannot differentiate between options a, b, and c.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippet database lacks general-purpose documentation for the datetime module, particularly regarding subtraction and timedelta properties.", + "missing_concepts": [ + "Datetime subtraction returns a timedelta", + "Using .days to extract an integer from a timedelta", + "Incompatibility of timedelta and integer addition", + "datetime constructor constraints (day must be > 0)" + ], + "proposed_fix": "Add a foundational snippet covering datetime arithmetic and the timedelta class." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Datetime Arithmetic and Timedeltas\nContent: \n- Subtracting two `datetime` objects (e.g., `dt1 - dt2`) produces a `timedelta` object.\n- To get the number of days as an integer, access the `.days` attribute: `(dt1 - dt2).days`.\n- You cannot add an integer directly to a `timedelta` or `datetime` object (e.g., `td + 1` is an error).\n- `datetime(year, month, day)` requires month 1-12 and day 1-31.", + "why_helpful": "This provides the necessary rules to solve the problem logically rather than by pattern-matching an identical question.", + "why_maybe_unnecessary": "The information is contained within one of the past exam items, but that item is question-specific rather than a general rule.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:35:15Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q11", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q11", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "8-dict_comprehension-1", + "question": "You have a list of strings called list_1, in which every element is unique.\n\nWhich of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?", + "options": { + "a": "{item: len(item) for item in list_1}", + "b": "[len(item) for item in list_1]", + "c": "{item for item in list_1 if len(item) > 0}", + "d": "{len(item): item for item in list_1}" + }, + "correct": "a", + "explanation": "Option A is the dictionary comprehension that maps each string to its length. Option B creates a list, option C creates a set, and option D reverses the intended key-value relation.", + "code_context": "list_1 contains unique strings." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "This snippet shows the literal structure of a dictionary '{1: 'I', 2: 'II'}', which helps a student recognize that dictionaries use curly braces and key:value pairs separated by colons." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "This snippet shows the literal structure of a dictionary '{1: 'I', 2: 'II'}', which helps a student recognize that dictionaries use curly braces and key:value pairs separated by colons." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Reiterates the terminology of keys and values in the context of creating a dictionary." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "This is the exact same question, options, and explanation as the current question." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This is a near-identical question using different variable names (words instead of list_1) but the same logic and target output." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "This snippet shows the literal structure of a dictionary '{1: 'I', 2: 'II'}', which helps a student recognize that dictionaries use curly braces and key:value pairs separated by colons.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Reiterates the terminology of keys and values in the context of creating a dictionary.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the near-identical pieces provide the answer directly, the general snippets do not explain the 'comprehension' syntax ({key: value for item in list}). A student with zero knowledge would know a dictionary uses {k:v} but wouldn't necessarily understand the 'for item in list_1' part inside the braces.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing a general explanation of dictionary and list comprehension syntax.", + "missing_concepts": [ + "dictionary comprehension syntax", + "list comprehension syntax" + ], + "proposed_fix": "Add a foundational snippet explaining the structure of comprehensions (e.g., '{key_expr: value_expr for item in iterable}')." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Python Syntax' snippet specifically for Dictionary Comprehensions showing: {k: v for k, v in something} and {item: len(item) for item in list}.", + "why_helpful": "It would bridge the gap between knowing what a dictionary looks like and understanding how to build one dynamically from a list.", + "why_maybe_unnecessary": "The existing 'past exam' pieces already cover this specific use case, but a general principle is missing.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:35:47Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?\nA\nB\nC\nD\nA\nThis is a standard dictionary comprehension. Option B is a list comprehension, Option C is a se" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q12", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q12", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "8-list_comprehension-1", + "question": "Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case.\n\nYou'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version.\n\nWhich of the following code lines will achieve what you want?", + "options": { + "a": "[letter.upper() if letter.islower() else letter.lower() for letter in list_1]", + "b": "[letter.upper() for letter in list_1 if letter.islower() else letter.lower()]", + "c": "[letter.lower() for letter in list_1 if letter.isupper()] + [letter.upper() for letter in list_1 if letter.islower()]", + "d": "[letter.capitalize() for letter in list_1 if not letter.iscapitalized()]" + }, + "correct": "a", + "explanation": "Option A flips the case of each letter while preserving the original order of the list. The other options either have invalid comprehension syntax, change the order, or use a non-existent string method.", + "code_context": "list_1 contains letters with mixed case." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This snippet is the only one that mentions the concept of upper and lower case letters ('Upper case and lower case versions of a letter count as'), which is relevant to the problem's domain, even though it does not provide the necessary code syntax." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This snippet is the only one that mentions the concept of upper and lower case letters ('Upper case and lower case versions of a letter count as'), which is relevant to the problem's domain, even though it does not provide the necessary code syntax." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Shows basic string input handling, though focused on phone numbers rather than case manipulation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This snippet is the only one that mentions the concept of upper and lower case letters ('Upper case and lower case versions of a letter count as'), which is relevant to the problem's domain, even though it does not provide the necessary code syntax.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Shows basic string input handling, though focused on phone numbers rather than case manipulation.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets cover the fundamental syntax of list comprehensions, nor the ternary operator (if-else) used within them. Furthermore, specific string methods like .upper(), .lower(), and .islower() are not documented in the provided snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provide no information on list comprehension syntax or conditional logic within comprehensions.", + "missing_concepts": [ + "List comprehension basic syntax: [expression for item in list]", + "Ternary operator/Conditional comprehension: [val_if_true if condition else val_if_false for item in list]", + "String methods: .upper(), .lower(), .islower(), .isupper()" + ], + "proposed_fix": "Add a snippet family explaining list comprehensions, specifically highlighting the syntax for conditional values (ternary if-else) versus conditional filtering." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'List Comprehensions with If-Else' showing the syntax: [x.upper() if x.islower() else x.lower() for x in list].", + "why_helpful": "This would directly allow a student to identify the correct syntax in option (a) and recognize the syntax error in option (b).", + "why_maybe_unnecessary": "The topic is list comprehensions, so it is likely intended to be covered in a dedicated card that was not in the candidate list.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:36:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q13", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q13", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Basic logic", + "question": "Suppose you have three variables x, y, z as follows:\n\nx = 'x'\ny = 3\nz = 3.0\n\nWhat are the outputs of the following lines of code?\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)", + "options": { + "a": "False\nTrue\nFalse\nFalse", + "b": "True\nTrue\nTrue\nTrue", + "c": "False\nFalse\nFalse\nTrue", + "d": "True\nFalse\nFalse\nFalse" + }, + "correct": "a", + "explanation": "The string 'x' is not equal to the integer 3 or the float 3.0, so the first and third comparisons are False. The integer 3 and float 3.0 are equal in Python, so the second comparison is True. The chained comparison is False because x == y is False.", + "code_context": "x = 'x'\ny = 3\nz = 3.0\nprint(x == y)\nprint(y == z)\nprint(x == z)\nprint(x == y == z)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "While not the identical question, it features the same variable types (int 3, float 3.0, and string '3') and requires understanding that a string is not equal to its numeric equivalent (x != z) unless converted (x == int(z))." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "While not the identical question, it features the same variable types (int 3, float 3.0, and string '3') and requires understanding that a string is not equal to its numeric equivalent (x != z) unless converted (x == int(z))." + }, + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Reinforces the relationship between string '3', integer 3, and float 3.0 using similar logical expressions." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "Uses nearly identical variables (string, int, float) and the exact same four print lines. Crucially, the explanation explicitly defines that 3 == 3.0 is True and that chained comparisons (x == y == z) expand to (x == y) and (y == z)." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "rationale": "While not the identical question, it features the same variable types (int 3, float 3.0, and string '3') and requires understanding that a string is not equal to its numeric equivalent (x != z) unless converted (x == int(z)).", + "critical_piece_ids": [ + "exam-midterm_2024-2-w2-conditions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "rationale": "Reinforces the relationship between string '3', integer 3, and float 3.0 using similar logical expressions.", + "critical_piece_ids": [ + "exam-trial_midterm-4-w1-objects-and-names" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-13-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Snippet 'exam-intro_python_sample_final_24_25-13-w1-objects-and-names' contains the specific logic for every part of the question, including the chained comparison rule and the fact that 3 equals 3.0 but not '3'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets rely heavily on specific past exam questions rather than general principles of Python equality and logic.", + "missing_concepts": [ + "Chained comparisons (x == y == z) logic expansion", + "Equality between integers and floats (3 == 3.0)", + "Inequality between strings and numbers ('3' == 3 is False)" + ], + "proposed_fix": "Add a general-purpose 'Basic Logic and Equality' snippet covering these three rules clearly." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Python Equality Rules:\n1. Numbers vs Strings: A string is never equal to a number (e.g., '3' == 3 is False).\n2. Integers vs Floats: If values are the same, they are equal (e.g., 3 == 3.0 is True).\n3. Chained Comparisons: x == y == z is equivalent to (x == y) and (y == z). Both checks must be True for the result to be True.", + "why_helpful": "It provides the underlying theory needed to solve this and many similar logic questions without requiring an identical past exam reference.", + "why_maybe_unnecessary": "The student can find the answer in the sample final exam snippet, but a general rule is more robust for variations.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:37:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)\nA\nB\nC\nD\nA\n'3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is False. x == y == z evaluates as (x == y) and (y == z), which is False and True, resulting in False." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. C" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q14", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q14", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Basic loop", + "question": "You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. In the first iteration, just take the previous number to be 0.\n\nFor example:\n1 + 0 = 1\n2 + 1 = 3\n3 + 2 = 5\n...\n10 + 9 = 19\n\nChoose the program that will print the correct output (i.e. only the sums).", + "options": { + "a": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i", + "b": "i = 0\nwhile i <= 10:\n print(i + (i - 1))\n i += 1", + "c": "Both of the above", + "d": "Neither of the above" + }, + "correct": "a", + "explanation": "A keeps track of the previous number and prints each sum correctly from 1 + 0 through 10 + 9. B does not use the required previous-value logic and prints the wrong sums.", + "code_context": "previous = 0\nfor i in range(1, 11):\n print(i + previous)\n previous = i" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Excluding the identical piece, this is the only other snippet that focuses on the concept of 'computing the sum of values,' which is a core part of the question's logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Excluding the identical piece, this is the only other snippet that focuses on the concept of 'computing the sum of values,' which is a core part of the question's logic." + }, + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Deals with pairs of numbers adding up to a target, which introduces the logic of relationships between multiple integers." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "snippet_id": "item:exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "This is an exact match for the question regarding summing the current and previous number in a loop from 1 to 10." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Excluding the identical piece, this is the only other snippet that focuses on the concept of 'computing the sum of values,' which is a core part of the question's logic.", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "rationale": "Deals with pairs of numbers adding up to a target, which introduces the logic of relationships between multiple integers.", + "critical_piece_ids": [ + "exam-extra_practice-10-w3-higher-order-patterns" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "medium", + "rationale": "While an identical past exam snippet exists, its internal explanation is contradictory (it mentions Option B is correct while the code context and answer key indicate A). Furthermore, there are no snippets explaining the critical 'range(1, 11)' boundary behavior or the general syntax of 'for' vs 'while' loops for a student with zero Python knowledge.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippet bank lacks foundational documentation on loop iteration and the range function.", + "missing_concepts": [ + "range(start, stop) inclusive/exclusive bounds", + "Basic for-loop vs while-loop mechanics", + "State-tracking patterns (accumulating or referencing previous values) within a loop body" + ], + "proposed_fix": "Add a 'Loop Fundamentals' snippet that explains how range(1, 11) produces numbers 1-10 and illustrates how to update a state variable like 'previous' at the end of each iteration." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: For Loops and Range Bounds. Content: range(start, stop) includes the start number but stops BEFORE the stop number (e.g., range(1, 11) gives 1 to 10). To track a 'previous' value in a loop, initialize a variable outside (previous = 0) and update it inside the loop after using it (previous = i), so it holds the old value in the next iteration.", + "why_helpful": "Provides the conceptual tools to understand why Option A is correct and why range(1, 11) is the correct bound, rather than just relying on a potentially confusing past exam match.", + "why_maybe_unnecessary": "An exact match exists, but it is too specific and currently contains a misleading explanation in the search text.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:37:55Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).\nA\nB\nC\nD\nB\nOption B correctly updates the 'previous' state at the end of each iteration to match the logic of the target output." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q15", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q15", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Basic scope", + "question": "Executing the following program will produce an error. Why?\n\ndef cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)", + "options": { + "a": "Result is a local variable and cannot be referenced outside of the function", + "b": "** is not a valid Python operator.", + "c": "The syntax of the f-string is incorrect.", + "d": "You can only use either print or return, but not both." + }, + "correct": "a", + "explanation": "result is created inside the function, so it is local to cube and is not available at the top level where print(result) is executed.", + "code_context": "def cube(num):\n result = num ** 3\n return f'The cube of {num} is: {result}.'\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Directly defines local names as those assigned inside a function and explicitly states they are 'Only known inside the function', which explains the error perfectly for a non-programmer." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Directly defines local names as those assigned inside a function and explicitly states they are 'Only known inside the function', which explains the error perfectly for a non-programmer." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a practical exam-style example where a variable in one function's scope is inaccessible elsewhere, reinforcing the 'local' concept." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "rationale": "This is an exact match for the question, featuring the same 'cube' function, 'result' variable, and explanation." + }, + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "rationale": "Near-identical logic using a 'power' function instead of 'cube'; the explanation for the error is identical." + }, + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Near-identical logic and identical explanation for why the variable cannot be accessed outside the function." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "Directly defines local names as those assigned inside a function and explicitly states they are 'Only known inside the function', which explains the error perfectly for a non-programmer.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "Provides a practical exam-style example where a variable in one function's scope is inaccessible elsewhere, reinforcing the 'local' concept.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-2-w3-scope" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The lecture snippet provides a clear, dictionary-like definition of local scope. Furthermore, there is an exact duplicate of this question in the past exam items.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The available lecture snippet is sufficient to derive the answer logically.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:38:19Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?\na\nb\nc\nd\nb\nThe global variable 'a' is accessible inside the inner function without error. The code evaluates to inner(5) * 3 = (1 + 5 + 4) * 3 = 30." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q16", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q16", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "List lambda", + "question": "You already have a list named list_1 with 2 lambda functions as follows:\n\nlist_1 = [lambda a, b: a + b, lambda a, b: a * b]\n\nWhat would be printed by the following code snippet?\nprint(list_1[0](1, 2) ** list_1[1](1, 2))", + "options": { + "a": "6", + "b": "7", + "c": "8", + "d": "9" + }, + "correct": "d", + "explanation": "list_1[0](1, 2) returns 3 and list_1[1](1, 2) returns 2, so the expression becomes 3 ** 2, which is 9.", + "code_context": "list_1 = [lambda a, b: a + b, lambda a, b: a * b]\nprint(list_1[0](1, 2) ** list_1[1](1, 2))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "This family is the only other one dealing with higher-order functions (functions in a list context) and explicitly demonstrates the exponentiation operator (**), which is critical for the final calculation." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "This family is the only other one dealing with higher-order functions (functions in a list context) and explicitly demonstrates the exponentiation operator (**), which is critical for the final calculation." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Explains how functions take integers as arguments and are called, which helps interpret the list_1[0](1, 2) syntax as a function call." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "snippet_id": "item:exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "rationale": "This piece contains the exact code and question from the current exam, providing the full solution and explanation." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "This family is the only other one dealing with higher-order functions (functions in a list context) and explicitly demonstrates the exponentiation operator (**), which is critical for the final calculation.", + "critical_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "Explains how functions take integers as arguments and are called, which helps interpret the list_1[0](1, 2) syntax as a function call.", + "critical_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the exponentiation operator and function arguments are covered in other snippets, the 'lambda' keyword and the specific syntax of calling a function stored inside a list index are not explained anywhere except in the near-identical past exam piece.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The primary gap is the definition and syntax of lambda functions and the concept of first-class functions (storing and calling functions from a list).", + "missing_concepts": [ + "lambda functions", + "storing functions in lists", + "calling functions via list indexing syntax: list[index](args)" + ], + "proposed_fix": "Add a snippet or piece that explains that 'lambda' creates a small anonymous function and shows how a list of functions can be accessed and called using parentheses immediately after the index." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet under 'Higher-Order Functions' or 'Lambdas' that shows: 'functions = [lambda x: x+1, lambda x: x*2]; print(functions[0](5)) # outputs 6'.", + "why_helpful": "This would bridge the gap between knowing what a list is and knowing how to interact with functions stored inside one, specifically for students with zero prior knowledge.", + "why_maybe_unnecessary": "The identical past-exam piece already exists, so students might simply find the direct answer if it is included in their cheat sheet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:38:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))\nA\nB\nC\nD\nD\nlist_1[0](1, 2) is 1 + 2 = 3. list_1[1](1, 2) is 1 * 2 = 2. 3 ** 2 = 9." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-15-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-15-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Assume you already have a variable a, which is an integer between 1 and 4.\nWhat is the ​output of the following ​code snippet?" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q17", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q17", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "List logic", + "question": "You have the following function called main:\n\ndef main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]\n\nWhat are the outputs of the following lines:\nmain([[], (), []])\nmain([[1], [2, 2], [3, 3, 3]])\nmain([[1], [2], [3]])", + "options": { + "a": "True\nTrue\nTrue", + "b": "True\nFalse\nTrue", + "c": "True\nFalse\nFalse", + "d": "False\nFalse\nTrue" + }, + "correct": "a", + "explanation": "For the first call, each element has length 0, so y becomes [True, True, True] and the comparison is True. In the second and third calls, each element has non-zero length, so y becomes [False, False, False] and the chained equality is also True.", + "code_context": "def main(x):\n y = []\n for i in x:\n if len(i) == 0:\n y.append(True)\n else:\n y.append(False)\n return y[0] == y[1] == y[2]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "This snippet mirrors the exact structural pattern of the question: initializing an empty list, looping through an input list, using a conditional to append values, and returning a result derived from the new list." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "This snippet mirrors the exact structural pattern of the question: initializing an empty list, looping through an input list, using a conditional to append values, and returning a result derived from the new list." + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Demonstrates the use of the len() function and the equality operator (==) in a return statement, which are key components of the logic in the main question." + }, + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "rationale": "Provides an additional example of the list-building pattern (loop + append) which reinforces the execution flow of the provided code context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "This snippet mirrors the exact structural pattern of the question: initializing an empty list, looping through an input list, using a conditional to append values, and returning a result derived from the new list.", + "critical_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Demonstrates the use of the len() function and the equality operator (==) in a return statement, which are key components of the logic in the main question.", + "critical_piece_ids": [ + "exam-extra_practice-1-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "rationale": "Provides an additional example of the list-building pattern (loop + append) which reinforces the execution flow of the provided code context.", + "critical_piece_ids": [ + "exam-trial_midterm-6-w2-conditions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-15-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-1-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the basic blocks (loops, appends, len, equality). However, a student with zero knowledge might not realize that 'False == False == False' evaluates to True (chained equality) or that empty tuples () and lists [] both have length 0.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing explicit explanation of chained equality behavior and the specific length of empty containers (lists/tuples).", + "missing_concepts": [ + "chained equality (a == b == c)", + "length of empty containers ([], ())" + ], + "proposed_fix": "Add a snippet demonstrating that len([]) and len(()) are both 0, and another showing how chained equality works with Boolean values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet from Week 2 (Conditions) or Week 2 (Lists) that explicitly shows: 1) len([]) == 0 and len(()) == 0. 2) The result of False == False == False.", + "why_helpful": "This eliminates the 'zero-knowledge' barrier regarding the specific behavior of length checks on different types and the non-intuitive evaluation of chained False values.", + "why_maybe_unnecessary": "Students might infer len(empty) is 0, but the chained equality is a common pitfall.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:39:03Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q18", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q18", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "List loop", + "question": "How do you break a list into a list of lists, in which a sub-list consists of 3 values each?\n\nFor example, if the original list x is:\nx = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']\nthen how would you create:\ny = [['a', 'b', 'c'], ['d', 'e', 'f'], ['g', 'h', 'i']]", + "options": { + "a": "y = [x[i:i + 3] for i in range(0, 7, 3)]", + "b": "y = [x[0::3] for i, enumerate(x)]", + "c": "Both of the above work", + "d": "Neither of the above works" + }, + "correct": "a", + "explanation": "A slices the list into consecutive groups of three elements. B does not produce the required nested lists.", + "code_context": "x = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i']" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "While the identical piece is excluded, this family provides the closest relevant logic regarding list manipulation and slicing (Option B mentions slicing to step), which helps a student understand list indexing/stepping even if it doesn't solve the 'list of lists' problem directly." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "While the identical piece is excluded, this family provides the closest relevant logic regarding list manipulation and slicing (Option B mentions slicing to step), which helps a student understand list indexing/stepping even if it doesn't solve the 'list of lists' problem directly." + }, + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Provides general context on working with lists and functional return values, which is helpful for understanding the structure of list comprehensions." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "This piece contains the exact same question and explains why Option A is the correct answer using the range(0, 7, 3) logic." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "While the identical piece is excluded, this family provides the closest relevant logic regarding list manipulation and slicing (Option B mentions slicing to step), which helps a student understand list indexing/stepping even if it doesn't solve the 'list of lists' problem directly.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "rationale": "Provides general context on working with lists and functional return values, which is helpful for understanding the structure of list comprehensions.", + "critical_piece_ids": [ + "exam-extra_practice-1-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-18-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-18-w2-conditions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include a near-identical past exam question that explicitly explains the correct logic for this specific problem (breaking a list into groups of 3 using range and slicing).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets contain the exact answer. However, if that specific piece were missing, there would be a significant gap in explaining list comprehensions and the range(start, stop, step) function for zero-knowledge users.", + "missing_concepts": [ + "List comprehensions with nested slicing", + "range(start, stop, step) mechanics" + ], + "proposed_fix": "Add a conceptual snippet explaining how list comprehensions work as 'for loops inside brackets' and how range(0, 10, 3) produces indices for chunking." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'List Chunking Patterns' snippet that explains the syntax: [x[i:i+n] for i in range(0, len(x), n)].", + "why_helpful": "This is a common exam pattern (list of lists) that is difficult to derive without knowing both slicing and list comprehension syntax.", + "why_maybe_unnecessary": "The sample exam piece already covers it, but a general rule is more educational than a specific exam answer.", + "recommended_direction": "consider_instead" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:39:14Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-18-w2-conditions", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nA\nB\nC\nD\nA\nOption A uses range(0, 7, 3) which generates 0, 3, 6. The slices x[0:3], x[3:6], and x[6:9] correctly partition the list." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q19", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q19", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-1", + "question": "You have to write a function called main that accepts a dictionary as an input argument. Both the keys and the values of the input are integers.\n\nReturn another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary, whose keys are smaller than, or equal to, the output key in question.\n\nFor example:\nmain({5: 1, 2: 5, 4: 2})\nshould return a dictionary that is equal to:\n{5: 8, 2: 5, 4: 7}\n\nWhich of the following programs works as intended?", + "options": { + "a": "def main(d1):\n running_total = 0\n d2 = {}\n for key in sorted(d1.keys()):\n running_total += d1[key]\n d2[key] = running_total\n return d2", + "b": "def main(d):\n result = {}\n for output_key in d.keys():\n result[output_key] = sum([v for k, v in d.items() if k <= output_key])\n return result", + "c": "Both of the above works as intended", + "d": "None of the above work as intended" + }, + "correct": "c", + "explanation": "Option A builds cumulative sums over the sorted keys, and option B directly computes the sum of values whose keys are less than or equal to each output key. Both produce the intended dictionary values.", + "code_context": "Example target behavior:\nmain({5: 1, 2: 5, 4: 2})\n# returns a dictionary equal to {5: 8, 2: 5, 4: 7}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows the basic pattern of iterating through data to build a dictionary mapping keys to calculated values, which is the core structure of both options." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows the basic pattern of iterating through data to build a dictionary mapping keys to calculated values, which is the core structure of both options." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a dictionary with numeric values and the need to perform arithmetic (average/sum) on those values." + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Shows a function returning the sum of multiple values, which helps a student understand the 'sum()' part of Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Shows the basic pattern of iterating through data to build a dictionary mapping keys to calculated values, which is the core structure of both options.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a dictionary with numeric values and the need to perform arithmetic (average/sum) on those values.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Shows a function returning the sum of multiple values, which helps a student understand the 'sum()' part of Option B.", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While existing snippets show dictionary creation and basic summing, they do not explain 'sorted(d.keys())' or the conditional logic 'if k <= output_key' inside a list comprehension. A student without prior knowledge would not know how dictionary keys are ordered by default or how to filter them based on size.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing concepts of dictionary key sorting and conditional filtering during iteration.", + "missing_concepts": [ + "sorted() on dictionary keys", + "conditional list comprehensions", + "cumulative sum logic (running totals)" + ], + "proposed_fix": "Add a snippet demonstrating how to process dictionary entries based on key comparisons or a sorted sequence." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Processing Dictionaries with Key Comparisons. \nContent: To calculate values based on other entries, you can iterate through sorted keys: \n'for k in sorted(my_dict.keys()): running_total += my_dict[k]'. \nAlternatively, use a list comprehension with a condition: \n'[v for k, v in my_dict.items() if k <= limit]'.", + "why_helpful": "Directly explains the two different logic patterns (running total vs. filtered sum) used in the exam options.", + "why_maybe_unnecessary": "Only if the student is expected to infer 'sorted' and 'if' logic from general programming knowledge, which contradicts the 'almost zero prior knowledge' goal.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:39:35Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q20", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q20", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-2", + "question": "What is the result of the following program?\n\nl1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)", + "options": { + "a": "True", + "b": "False", + "c": "An error message.", + "d": "None of the above" + }, + "correct": "a", + "explanation": "zip(l1, l2) creates key-value pairs (1,2), (2,3), (3,4), and (4,5). enumerate(l2, 1) produces the same pairs, so d1 and d2 are equal and the comparison prints True.", + "code_context": "l1 = [1, 2, 3, 4]\nl2 = [2, 3, 4, 5]\n\nd1 = {}\nfor key, value in zip(l1, l2):\n d1[key] = value\n\nd2 = {}\nfor key, value in enumerate(l2, 1):\n d2[key] = value\n\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-65c4de2e9d", + "rationale": "Explains dictionary equality ({1:1,2:2}=={2:2,1:1} is True), which is the critical final logic check in the provided code." + }, + "top_three_snippets": [ + { + "item_id": "ks-65c4de2e9d", + "rationale": "Explains dictionary equality ({1:1,2:2}=={2:2,1:1} is True), which is the critical final logic check in the provided code." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Provides the specific values resulting from zip(l1, l2) and enumerate(l2, 1) for this problem pattern." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-65c4de2e9d", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Directly explains the outcome of comparing dictionaries created via zip and enumerate with identical source data." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-65c4de2e9d", + "rationale": "Explains dictionary equality ({1:1,2:2}=={2:2,1:1} is True), which is the critical final logic check in the provided code.", + "critical_piece_ids": [ + "ks-65c4de2e9d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "Provides the specific values resulting from zip(l1, l2) and enumerate(l2, 1) for this problem pattern.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-65c4de2e9d", + "rationale": "", + "needed_piece_ids": [ + "ks-65c4de2e9d" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam question provides the logic for zip and enumerate, while the lecture snippet confirms how the final dictionary comparison behaves.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing a general-purpose definition for zip() and enumerate() outside of specific past exam questions.", + "missing_concepts": [ + "zip() function mechanics", + "enumerate(sequence, start) mechanics" + ], + "proposed_fix": "Add a lecture-style snippet covering 'Iteration Utilities' (zip, enumerate, range) to provide general reference." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet for 'Iterables and zip/enumerate': 1) zip(l1, l2) pairs items by index. 2) enumerate(l1, start=1) pairs items with indices starting at 'start'.", + "why_helpful": "Allows students to solve any variation of this problem (e.g., if lists are different) rather than relying on a near-identical match.", + "why_maybe_unnecessary": "The specific pattern is heavily covered in past exams provided.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:40:12Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-24-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-24-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA The code will result in an error.\nB True\nC None\nD False\nEnd of test Trial Midterm - Introduction to Pyth" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?\nA\nB\nC\nD\nA\nBoth d1 and d2 result in the same dictionary: {1: 2, 2: 3, 3: 4, 4: 5}." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:ks-65c4de2e9d", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "ks-65c4de2e9d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Dictionaries\nSets of key:value pairs. Keys must be unique and immutable (hashable). Dictionaries are unordered for equality ({1:1,2:2}=={2:2,1:1} is True). Cannot be sorted. You can check membership with 'in' — this checks KEYS only. Keys() gives key sequence, values() gives valu" + } + ] + }, + { + "snippet_id": "item:ks-ab66f3bab6", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "ks-ab66f3bab6", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Methods vs functions\nMethods are functions attached to objects. Calling obj.method() is equivalent to Class.method(obj). For mutable objects: some methods CHANGE the object (e.g. list.sort()), some RETURN a value (e.g. list.index()). For immutable objects: methods always return a" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q21", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q21", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "trial-dictionary-3", + "question": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}\n\nThe following codes all print the same value, except one. Which one?", + "options": { + "a": "result = 0\nfor key, value in d1:\n result += value\nprint(result)", + "b": "result = 0\nfor key in d1.keys():\n result += d1[key]\nprint(result)", + "c": "result = 0\nfor value in d1.values():\n result += value\nprint(result)", + "d": "result = sum(d1.values())\nprint(result)" + }, + "correct": "a", + "explanation": "Iterating directly over a dictionary yields keys, not key-value pairs, so `for key, value in d1:` does not work as intended. The other three options all sum the dictionary values and print the same result.", + "code_context": "d1 = {1: 10, 2: 20, 3: 30, 4: 40}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "While it doesn't cover iteration, it establishes the concept of a dictionary having keys and values, which is the foundational data structure for the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "While it doesn't cover iteration, it establishes the concept of a dictionary having keys and values, which is the foundational data structure for the question." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Mentions calculating average sales from a dictionary, implying that accessing values is a standard operation, though it lacks the implementation code." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "This is the exact question and explanation. It explicitly states that 'for key, value in d1' only yields keys and causes a ValueError, which directly identifies 'a' as the outlier." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "rationale": "While it doesn't cover iteration, it establishes the concept of a dictionary having keys and values, which is the foundational data structure for the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Mentions calculating average sales from a dictionary, implying that accessing values is a standard operation, though it lacks the implementation code.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of the near-identical past exam piece makes the question perfectly answerable as it contains the specific rule needed to solve it. However, excluding that piece, the other snippets provide zero information on dictionary iteration syntax or the .keys()/.values() methods.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is a total lack of general documentation or code examples regarding dictionary iteration (items vs keys vs values) and the behavior of the built-in sum() function on dictionary views.", + "missing_concepts": [ + "Dictionary iteration: default yields keys", + "Dictionary methods: .items(), .keys(), .values()", + "ValueError when unpacking mismatched iteration yields", + "sum() function on dict_values" + ], + "proposed_fix": "Add a conceptual snippet explaining how to iterate over dictionaries in Python, highlighting the difference between iterating over the dictionary itself vs .items()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Iterating Over Dictionaries\nContent:\n- `for key in d:` Iterates over keys only.\n- `for key, value in d.items():` Iterates over key-value pairs (requires `.items()`).\n- `for value in d.values():` Iterates over values only.\n- `sum(d.values())` is a valid way to sum all numerical values in a dictionary.", + "why_helpful": "This provides the underlying logic for all four options in the question, allowing a student to identify why 'a' is incorrect without relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "The information is technically 'covered' by the past exam piece, but not in a generalizable format.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:40:45Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?\nA\nB\nC\nD\nA\nThis is a standard dictionary comprehension. Option B is a list comprehension, Option C is a se" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?\nA\nB\nC\nD\nC\nBoth methods correctly calculate the cumulative sums based on key values, though Option B is more efficient." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q22", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q22", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-1", + "question": "You have the following string\nx = 'Amsterdam'\n\nWhich script, using the count string method, would print the following value:\n1", + "options": { + "a": "print(count(x, 'a'))", + "b": "print(x.count('a'))", + "c": "Both scripts would deliver that result", + "d": "Neither script would deliver that result" + }, + "correct": "b", + "explanation": "The string method must be called on the string object itself, so `x.count('a')` is the correct form. In 'Amsterdam', there is one lowercase 'a', while the initial uppercase 'A' is not counted.", + "code_context": "x = 'Amsterdam'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-ab66f3bab6", + "rationale": "This lecture snippet explains the fundamental difference between functions and methods, specifically noting that methods are 'attached to objects' and called using 'obj.method()'. This directly addresses the choice between print(count(x, 'a')) and print(x.count('a'))." + }, + "top_three_snippets": [ + { + "item_id": "ks-ab66f3bab6", + "rationale": "This lecture snippet explains the fundamental difference between functions and methods, specifically noting that methods are 'attached to objects' and called using 'obj.method()'. This directly addresses the choice between print(count(x, 'a')) and print(x.count('a'))." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the .reverse() method, providing another example of the dot notation used for string/object methods, which reinforces the pattern needed for .count()." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "" + }, + { + "item_id": "ks-ab66f3bab6", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "This is the exact same question (word-for-word including the variable 'Amsterdam') from a past sample exam." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-ab66f3bab6", + "rationale": "This lecture snippet explains the fundamental difference between functions and methods, specifically noting that methods are 'attached to objects' and called using 'obj.method()'. This directly addresses the choice between print(count(x, 'a')) and print(x.count('a')).", + "critical_piece_ids": [ + "ks-ab66f3bab6" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the .reverse() method, providing another example of the dot notation used for string/object methods, which reinforces the pattern needed for .count().", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-22-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-22-w2-conditions" + ] + }, + { + "snippet_id": "item:ks-ab66f3bab6", + "rationale": "", + "needed_piece_ids": [ + "ks-ab66f3bab6" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The past exam piece provides the exact answer and explanation. Even excluding that, the lecture snippet on 'Methods vs functions' explicitly explains the dot notation (obj.method()) required for the correct answer.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the syntax is covered, the concept of case-sensitivity (why 'A' is not counted) is only mentioned in the question's explanation but not explicitly defined in the general snippets provided.", + "missing_concepts": [ + "string method case-sensitivity" + ], + "proposed_fix": "Add a snippet or note about common string methods (like count, find, index) specifically mentioning that string comparisons in Python are case-sensitive." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:40:56Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-22-w2-conditions", + "snippet_label": "String Operations and Methods", + "week": 4, + "topic": "String Operations and Methods", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?\nA\nB\nC\nD\nB\nThe count() method is a string method, not a standalone function. It is called using the dot notation on a string object." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:ks-ab66f3bab6", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "ks-ab66f3bab6", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Methods vs functions\nMethods are functions attached to objects. Calling obj.method() is equivalent to Class.method(obj). For mutable objects: some methods CHANGE the object (e.g. list.sort()), some RETURN a value (e.g. list.index()). For immutable objects: methods always return a" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q23", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q23", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-2", + "question": "Take a look at the following function definition.\n\ndef calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result\n\nWhich of the following function calls would return the number 30 as a result?", + "options": { + "a": "calculation(lambda x: x + 5, 1, 2, 3, 4)", + "b": "calculation(lambda x: x**2, 1, 2, 3, 4)", + "c": "Both function calls would lead to that result", + "d": "Neither function call would lead to that result" + }, + "correct": "c", + "explanation": "For option A, the function returns 6 + 7 + 8 + 9 = 30. For option B, it returns 1 + 4 + 9 + 16 = 30. Both calls therefore produce 30.", + "code_context": "def calculation(func, *args):\n result = 0\n for el in args:\n result += func(el)\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-3", + "rationale": "This meta-snippet provides the critical conceptual bridges: explaining that *args creates a tuple and instructing the user to apply the lambda/function transformation to elements of an iterable." + }, + "top_three_snippets": [ + { + "item_id": "aiq-3", + "rationale": "This meta-snippet provides the critical conceptual bridges: explaining that *args creates a tuple and instructing the user to apply the lambda/function transformation to elements of an iterable." + }, + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "rationale": "Shows a near-identical structural pattern of a function using *args and a 'for num in args' loop to accumulate a result." + }, + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Demonstrates the concept of higher-order functions by showing how one function (square or cube) can be applied to elements of a list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "" + }, + { + "item_id": "aiq-3", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "snippet_id": "item:exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "This piece contains the exact same question and explains the calculation (6+7+8+9=30 and 1+4+9+16=30) leading to the correct answer." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-3", + "rationale": "This meta-snippet provides the critical conceptual bridges: explaining that *args creates a tuple and instructing the user to apply the lambda/function transformation to elements of an iterable.", + "critical_piece_ids": [ + "aiq-3" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "rationale": "Shows a near-identical structural pattern of a function using *args and a 'for num in args' loop to accumulate a result.", + "critical_piece_ids": [ + "exam-midterm_2024-14-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "Demonstrates the concept of higher-order functions by showing how one function (square or cube) can be applied to elements of a list.", + "critical_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-23-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-23-w3-arguments" + ] + }, + { + "snippet_id": "item:aiq-3", + "rationale": "", + "needed_piece_ids": [ + "aiq-3" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The collection includes a near-identical past exam question that directly confirms the logic, plus conceptual snippets explaining lambda application and *args behavior.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets cover the identical question and the core concepts, but a dedicated 'Lambda Syntax' reference would help students understand the 'x: x + 5' part more clearly if the identical question weren't available.", + "missing_concepts": [ + "Explicit lambda syntax explanation (parameters vs return expression)" + ], + "proposed_fix": "Add a new AI-generated snippet or textbook piece specifically defining lambda syntax with a simple example like 'lambda x: x + 1'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet piece: 'Lambda Functions (Anonymous Functions): Syntax: lambda arguments: expression. For example, lambda x: x + 5 takes x and returns x plus 5.'", + "why_helpful": "It clarifies the specific syntax used in the options (a) and (b) for students who haven't seen lambda before.", + "why_maybe_unnecessary": "The identical past exam question already explains the math for both lambda cases.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:41:29Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-23-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Which of the following function calls would return the number 30 as a result?\nA\nB\nC\nD\nC\nThe first call sums (6+7+8+9)=30. The second call sums (1+4+9+16)=30." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. C" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:trial-final-exam-solutions-introduction-to-python-3077951-q24", + "question_id": "trial-final-exam-solutions-introduction-to-python-3077951-q24", + "exam_id": "trial-final-exam-solutions-introduction-to-python-3077951", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "trial-functions-3", + "question": "If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula:\nπr²\n\nSuppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area?", + "options": { + "a": "import math\nprint(math.pi * r ** 2)", + "b": "from math import pi\nprint(pi * r ** 2)", + "c": "import math as constants\nprint(math.pi * r ** 2)", + "d": "from math import pi as constant\nprint(constant * r ** 2)" + }, + "correct": "c", + "explanation": "Option C imports the module under the name `constants`, but then tries to access `math.pi`, where `math` is not defined. The other options all reference pi correctly and would print the correct area.", + "code_context": "Area formula: πr²" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "This snippet provides the syntax for the exponentiation operator (**2), which is necessary to understand the radius squared part of the area formula (πr²)." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "This snippet provides the syntax for the exponentiation operator (**2), which is necessary to understand the radius squared part of the area formula (πr²)." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Briefly mentions variable context, which is relevant as the question assumes a variable 'r' is already defined." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "snippet_id": "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "rationale": "This piece is an exact duplicate of the current question, including the correct answer (C) and a clear explanation of the module aliasing logic." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "This snippet provides the syntax for the exponentiation operator (**2), which is necessary to understand the radius squared part of the area formula (πr²).", + "critical_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "Briefly mentions variable context, which is relevant as the question assumes a variable 'r' is already defined.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-13-w3-higher-order-patterns" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "Excluding the near-identical past exam piece, none of the candidate snippets explain Python import mechanisms or how aliasing a module with 'as' affects access to its attributes. A student without prior knowledge would not know why option C is incorrect.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a total lack of foundational material regarding imports and namespaces in the candidate set.", + "missing_concepts": [ + "import as ", + "from import ", + "attribute access (dot notation)" + ], + "proposed_fix": "Add a summary snippet that demonstrates the four common import styles: 'import math', 'import math as m', 'from math import pi', and 'from math import pi as p'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Python Imports Cheat Sheet' snippet: 'import math' -> access via math.pi; 'import math as m' -> access via m.pi; 'from math import pi' -> access via pi.", + "why_helpful": "This would provide the conceptual framework needed to evaluate all four options in the question systematically.", + "why_maybe_unnecessary": "The information exists in the duplicate past-exam piece, but the goal is to have general snippets that support transfer of knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T10:43:09Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Which script does NOT print the correct answer for the area of a circle?\nA\nB\nC\nD\nC\nIf math is imported as constants, it must be referred to as 'constants.pi'. 'math.pi' will no longer be available unless 'math' was also imported directly." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Corre" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/review_packets/round2_partial_and_insufficient.md b/data/vision_exam_pipeline/review_packets/round2_partial_and_insufficient.md new file mode 100644 index 0000000..2eeff9d --- /dev/null +++ b/data/vision_exam_pipeline/review_packets/round2_partial_and_insufficient.md @@ -0,0 +1,6635 @@ +# ROUND2 Partial and Insufficient Questions + +Generated from `data/vision_exam_pipeline/evaluations/round2.json`. + +## Summary + +- Weak questions total: **107** +- Partial: **36** +- Insufficient: **71** + +## By Exam + +- `final-exam-solutions-for-python-programming-62oop21`: 4 partial, 11 insufficient +- `final-exam-study-guide-trial-python-basics-2023`: 10 partial, 10 insufficient +- `introduction-to-python-trial-final-exam-solutions-py22`: 7 partial, 11 insufficient +- `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023`: 5 partial, 13 insufficient +- `resit-solutions-for-introduction-to-python-35761538`: 6 partial, 10 insufficient +- `sample-final-plus-answers`: 3 partial, 4 insufficient +- `trial-final-exam-solutions-introduction-to-python-3077951`: 1 partial, 12 insufficient + +## By Topic + +- Multiple choice: 1 partial, 4 insufficient +- 8-datetime-2: 0 partial, 2 insufficient +- Functions and Imports: 0 partial, 2 insufficient +- Sequences and Access: 0 partial, 2 insufficient +- String Methods: 0 partial, 2 insufficient +- 1_Basics_Logic_1: 0 partial, 1 insufficient +- 1_Basics_Logic_2: 0 partial, 1 insufficient +- 1_Basics_Variables_1: 1 partial, 0 insufficient +- 2-dictionaries - comprehension - 1: 1 partial, 0 insufficient +- 2-dictionaries - comprehension - 2: 1 partial, 0 insufficient +- 2-dictionaries - slicing - 1: 0 partial, 1 insufficient +- 2-list - comprehension - 1: 0 partial, 1 insufficient +- 2-list - comprehension - 2: 1 partial, 0 insufficient +- 2-list - manipulation - 1: 0 partial, 1 insufficient +- 2-list - manipulation - 2: 1 partial, 0 insufficient +- 2-list - slicing - 1: 0 partial, 1 insufficient +- 2-list - slicing - 2: 1 partial, 0 insufficient +- 3_Function_Argument_2: 0 partial, 1 insufficient +- 3_Function_Built-in_1: 0 partial, 1 insufficient +- 3_Function_Built-in_3: 1 partial, 0 insufficient +- 3_Function_Flexible-Argument_2: 1 partial, 0 insufficient +- 6-OOP-1: 0 partial, 1 insufficient +- 6-string - fstring - 1: 0 partial, 1 insufficient +- 6-string - fstring - 2: 0 partial, 1 insufficient +- 6-string - operations - 1: 0 partial, 1 insufficient +- 6-string - operations - 2: 1 partial, 0 insufficient +- 6-strings - find & replace - 1: 0 partial, 1 insufficient +- 6-strings - find - 2: 0 partial, 1 insufficient +- 6_OOP_Easy_1: 1 partial, 0 insufficient +- 6_OOP_Function_1: 1 partial, 0 insufficient +- 7-pandas - easy - 1: 0 partial, 1 insufficient +- 7-pandas - easy - 2: 0 partial, 1 insufficient +- 7-pandas - hard - 1: 0 partial, 1 insufficient +- 7-pandas - hard - 2: 1 partial, 0 insufficient +- 7-pandas - lambda - 1: 0 partial, 1 insufficient +- 7-pandas - lambda - 2: 1 partial, 0 insufficient +- 7-pandas-3: 1 partial, 0 insufficient +- 7-pandas-4: 0 partial, 1 insufficient +- 7-pandas-new_column-1: 0 partial, 1 insufficient +- 7-pandas-selection-1: 0 partial, 1 insufficient +- 7-pandas-string-1: 0 partial, 1 insufficient +- 8-comprehensions-1: 1 partial, 0 insufficient +- 8-comprehensions-2: 1 partial, 0 insufficient +- 8-datetime-1: 0 partial, 1 insufficient +- 8-dict_comprehension-1: 0 partial, 1 insufficient +- 8-list_comprehension-1: 0 partial, 1 insufficient +- 8_Datetime_Easy_1: 0 partial, 1 insufficient +- 8_Datetime_Easy_2: 1 partial, 0 insufficient +- 8_Datetime_Easy_3: 1 partial, 0 insufficient +- 8_Datetime_Function_1: 0 partial, 1 insufficient +- 8_Datetime_Function_2: 0 partial, 1 insufficient +- 8_Datetime_Function_3: 0 partial, 1 insufficient +- 8_Datetime_Hard_1: 0 partial, 1 insufficient +- 8_Datetime_Hard_2: 0 partial, 1 insufficient +- 8_Datetime_Hard_3: 0 partial, 1 insufficient +- 9_OOP_Easy_3: 1 partial, 0 insufficient +- 9_OOP_Function_2: 1 partial, 0 insufficient +- 9_OOP_Function_3: 1 partial, 0 insufficient +- 9_OOP_Hard_1: 1 partial, 0 insufficient +- 9_OOP_Hard_2: 1 partial, 0 insufficient +- animals methods: 0 partial, 1 insufficient +- Basic loop: 0 partial, 1 insufficient +- Basic loop 2: 0 partial, 1 insufficient +- Circle area imports and aliases: 0 partial, 1 insufficient +- Datetime parsing: 1 partial, 0 insufficient +- datetime weekly dates list: 0 partial, 1 insufficient +- Dictionaries and Mappings: 1 partial, 0 insufficient +- dictionary comprehension lengths: 0 partial, 1 insufficient +- Dictionary running totals: 0 partial, 1 insufficient +- Empty-sequence equality chain: 1 partial, 0 insufficient +- final-dictionary-1: 0 partial, 1 insufficient +- final-dictionary-2: 0 partial, 1 insufficient +- final-dictionary-3: 0 partial, 1 insufficient +- final-functions-1: 0 partial, 1 insufficient +- final-functions-2: 1 partial, 0 insufficient +- function defaults and loops: 1 partial, 0 insufficient +- keyword arguments: 1 partial, 0 insufficient +- List lambda: 0 partial, 1 insufficient +- List lambda 2: 0 partial, 1 insufficient +- List logic: 1 partial, 0 insufficient +- List logic 2: 0 partial, 1 insufficient +- List loop 2: 0 partial, 1 insufficient +- list slicing and sets: 0 partial, 1 insufficient +- Multiple choice - Question-ID: 355235: 0 partial, 1 insufficient +- Multiple choice - Question-ID: 357615: 0 partial, 1 insufficient +- pandas - easy - 3: 0 partial, 1 insufficient +- pandas - hard - 3: 1 partial, 0 insufficient +- pandas - lambda - 3: 0 partial, 1 insufficient +- pandas above average salary: 1 partial, 0 insufficient +- pandas date column from day month year: 0 partial, 1 insufficient +- pandas lambda output: 1 partial, 0 insufficient +- phone number formatting: 1 partial, 0 insufficient +- string - find - 3: 0 partial, 1 insufficient +- string - fstring - 3: 0 partial, 1 insufficient +- string - operations - 3: 1 partial, 0 insufficient +- Strings: 0 partial, 1 insufficient +- trial-dictionary-1: 0 partial, 1 insufficient +- trial-functions-3: 0 partial, 1 insufficient +- vehicle class defaults: 0 partial, 1 insufficient + +## Insufficient Questions + +Count: **71** + +### final-exam-solutions-for-python-programming-62oop21-q04 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `4` +- Topic: Strings +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all. + +For example, the following function calls should all return the boolean value True: +is_anagram("Old West Action", "Clint Eastwood") +is_anagram("eleven plus two", "twelve plus one") +is_anagram("I am a weakish speller", "William Shakespeare") + +while the following function call should return the boolean value False: +is_anagram("one plus two", "three") + +Which of the following code segments achieves what you want? + +**Options** +- `a`: def is_anagram(word_1, word_2): + return sorted(list(word_1.replace(" ", "").lower())) == sorted(list(word_2.replace(" ", "").lower())) +- `b`: def is_anagram(word_1, word_2): + return word_1.replace(" ", "").lower().sort() == word_2.replace(" ", "").lower().sort() +- `c`: def is_anagram(word_1, word_2): + return list(word_1.replace(" ", "").lower()).sort() == list(word_2.replace(" ", "").lower()) +- `d`: def is_anagram(word_1, word_2): + return sorted(list(word_1)).replace(" ", "").lower() == sorted(list(word_2)).replace(" ", "").lower() + +**Correct answer:** `a` + +**Official explanation:** A removes spaces, lowercases both strings, and compares the sorted letters. The other options misuse sort() or apply string operations to list objects in the wrong order. + +**Why not certain:** Excluding the direct past-exam matches, the available snippets do not explain string methods (.replace, .lower) or the return value of .sort(). A zero-knowledge student would not know that .sort() returns None, making options B/C look viable, nor would they know the order of operations for list vs string methods. + +**Gap summary:** The snippets fail to provide the semantic details of string manipulation and the specific behavior of sorting functions vs methods. + +**Missing concepts:** String methods: .replace() and .lower() (syntax and return type); The difference between the sorted() function (returns new list) and the .sort() method (returns None); Method chaining order: applying string methods to the result of list() will fail +**Suggested fix:** Add a reference snippet for 'Common String & List Operations' that explicitly contrasts sorted(L) with L.sort() and lists common string methods like .replace() and .lower(). + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value). + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value). +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Provides a basic context for working with lists of strings and checking conditions, though it lacks specific method details. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why excluded: This item is an exact match for the current exam question text regarding is_anagram. +- `exam-Test Exam 07-06-22-4-w2-conditions`: Conditions [w2-conditions] + Why excluded: This item is an exact match for the current exam question text regarding is_anagram. + +### final-exam-solutions-for-python-programming-62oop21-q08 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `8` +- Topic: 7-pandas-4 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have two DataFrames: df1 and df2. They look like this when printed: + +print(df1) + + Age Height Female City Language +0 23 167 True Berlin German +1 36 175 True Frankfurt German +2 17 182 False Antwerpen Dutch +3 25 177 True Eindhoven Dutch +4 36 178 False Lyon French +5 52 185 False Basel German +6 46 168 True Innsbruck German + +print(df2) + + Age Height Female City Language +5 52 185 False Basel German +4 36 178 False Lyon French +1 36 175 True Frankfurt German +6 46 168 True Innsbruck German +0 23 167 True Berlin German + +Which of the following code segments could have created df2 from df1? + +**Options** +- `a`: df1.loc[df1["Language"].isin(["French", "German"])].sort_values("Height", ascending=False) +- `b`: df1.loc[df1["Language"] != "Dutch"].sort_values("Age", ascending=False) +- `c`: df1.loc[~df1["Language"].isin(["Dutch"]), ["Age", "Height", "City", "Language"]].sort_index(ascending=False) +- `d`: df1.loc[df1["Language"] != "Dutch"].sort_index(axis=1) + +**Correct answer:** `a` + +**Official explanation:** Option A filters out the Dutch rows and then sorts the remaining rows by Height in descending order, matching df2 exactly. + +**Why not certain:** The available snippets only mention 'Inspecting and Selecting Data' but do not provide the syntax or behavior for .isin(), .sort_values(), or .sort_index(). A student without prior knowledge would not be able to distinguish between the sorting and filtering methods used in the options. + +**Gap summary:** Missing critical documentation on pandas filtering (isin) and sorting (sort_values/sort_index). + +**Missing concepts:** pandas.Series.isin(); pandas.DataFrame.sort_values(); pandas.DataFrame.sort_index(); Boolean indexing on string columns +**Suggested fix:** Add a dedicated snippet for 'Pandas Sorting and Filtering' that includes examples of selecting rows based on categories (isin) and reordering rows by column values. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Provides basic context on pandas DataFrame operations and column-based logic. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q12 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `12` +- Topic: 8-datetime-2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following definition for a Meeting class, which records basic information about meetings in a calendar application. + +You would like to add a method called lunch_meeting to this class, which returns a boolean value indicating whether there is any overlap between the official lunchtime (12:30 - 13:00) and the time of the meeting. + +For example, if you construct a Meeting object as: +my_meeting = Meeting('Ask for salary raise', "25-05-2022", start_time='12:00', length=45) +then the method call: +my_meeting.lunch_meeting() +should return the boolean value True. + +Which of the following code segments will achieve what you want? + +**Options** +- `a`: def lunch_meeting(self): + lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30) + lunch_end = lunch_start + timedelta(minutes=30) + return self.start < lunch_end and self.end > lunch_start +- `b`: def lunch_meeting(self): + return self.start < "13:00" and self.end > "12:30" +- `c`: def lunch_meeting(self): + return start_time <= "13:00" and start_time + length > "12:30" +- `d`: def lunch_meeting(self): + lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30) + lunch_end = datetime(self.date.year, self.date.month, self.date.day, 13, 0) + return self.start >= lunch_end or self.end <= lunch_start + +**Correct answer:** `a` + +**Official explanation:** Option A constructs the lunch interval on the same date and uses the standard interval-overlap check. The other options compare datetimes to strings, reference names that are not in scope, or use the non-overlap condition instead. + +**Why not certain:** None of the candidate snippets mention the 'datetime' or 'timedelta' modules. A student with zero prior knowledge would not know how to construct a datetime object using 'datetime(year, month, day, hour, minute)', how to add time using 'timedelta', or how to compare datetime objects. The logic for interval overlap is also not explained. + +**Gap summary:** The snippets provided focus on basic OOP and Pandas, completely missing the Week 8 'datetime' content required for this question. + +**Missing concepts:** datetime module syntax (datetime constructor); timedelta for time arithmetic; Datetime comparison operators (<, >); General logic for checking overlapping time intervals +**Suggested fix:** Add a new snippet for the datetime module that explains how to create timestamps and add durations, specifically including the standard interval overlap logic: (start1 < end2 and end1 > start2). + +**Best snippet** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides the foundational syntax for defining classes and initializing attributes, which helps the student understand the 'Meeting' class context. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q14 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `14` +- Topic: Basic loop 2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Which of the following code segments will print every even number between 0 and 20 (including 0 and 20) to the screen? + +**Options** +- `a`: for i in range(0, 20): + if i % 2 == 0: + print(i) +- `b`: i = 0 +while i <= 20: + if i % 2 == 0: + print(i) + i += 1 +- `c`: for i in list(range(0, 20)): + print(i if i % 2 == 0 else None) +- `d`: i = 0 +while i < 21: + print(i) + i += 1 + +**Correct answer:** `b` + +**Official explanation:** Option B checks every integer from 0 through 20 inclusive and prints only the even ones. Option A never reaches 20, option C also prints None for odd numbers, and option D prints every number. + +**Why not certain:** No snippet explains the modulo operator (%) used to check for even numbers (i % 2 == 0). Furthermore, there is no explanation that range(0, 20) is exclusive of 20, which is the primary reason option A is incorrect. + +**Gap summary:** The candidate snippets fail to define the two most critical mechanics for this question: the modulo operator for parity and the upper-bound behavior of the range() function. + +**Missing concepts:** modulo operator (%); range() upper bound exclusivity +**Suggested fix:** Add a foundational snippet from Week 2 (Loops) or Week 1 (Expressions) explaining that 'a % b' is the remainder and that 'range(start, stop)' stops before 'stop'. + +**Best snippet** +- `exam-Test Resit - Introduction to Python - 22/23-4-w2-loops`: Loops [w2-loops] + Why: This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D). + +**Top 3 snippets** +- `exam-Test Resit - Introduction to Python - 22/23-4-w2-loops`: Loops [w2-loops] + Why: This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D). +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: While the code is not shown, the text confirms that 'sum_even_in_list' involves filtering for even integers, which reinforces the concept of searching for parity-checking logic. + +**Minimal sufficient snippets** +- `exam-Test Resit - Introduction to Python - 22/23-4-w2-loops`: Loops [w2-loops] +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q16 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `16` +- Topic: final-dictionary-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have to write a function called main, which takes a list of unique integers as an argument and returns a dictionary. + +The output dictionary should consist of all key-value pairs for which the key is an element of the input list and the value is the next element of the input list. When there is no "next element" any more, leave the key-value pair out of the dictionary. + +For example, if your function is called as: +main([1, 3, 2, 4]) +then it should return the dictionary: +{1: 3, 3: 2, 2: 4} + +Which of the following programs work(s) according to the requirements? + +**Options** +- `a`: def main(l1): + result = {} + index = 0 + while True: + index = index + 1 + if index >= len(l1): + break + else: + result[l1[index]] = l1[index + 1] + return result +- `b`: def main(l1): + result = {} + for index, value in zip(l1[:-1], l1[1:]): + result[index] = value + return result +- `c`: Both programs work as required +- `d`: Neither of the two programs works as required + +**Correct answer:** `b` + +**Official explanation:** Option B correctly zips each element with the following element and builds the required dictionary. Option A starts at index 1 and eventually tries to access past the end of the list. + +**Why not certain:** The question relies entirely on understanding list slicing (l1[:-1], l1[1:]) and the zip() function to evaluate Option B. None of the provided snippets explain these concepts. Furthermore, the logic error in Option A (indexing) requires knowledge of 0-based indexing and the behavior of len() in loops, which is not clearly illustrated. + +**Gap summary:** Crucial sequence manipulation concepts (slicing and zipping) are missing. + +**Missing concepts:** List slicing (l1[:-1], l1[1:]); The zip() function for pairing elements; Off-by-one errors in while-loops with index incrementing +**Suggested fix:** Add a snippet or piece explaining the 'sliding window' pattern using zip and slicing, and another demonstrating why starting an index at 1 and accessing index+1 leads to errors. + +**Best snippet** +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question. + +**Top 3 snippets** +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question. +- `exam-midterm_2024-18-w2-loops`: Loops [w2-loops] + Why: Shows the pattern of initializing an empty dictionary 'y = {}' and populating it with 'y[key] = value' during a loop, which is central to evaluating Option A and B. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'Lists and Sets' piece clarifies dictionary equality, helping a student understand that the key-value pairs define the dictionary identity. + +**Minimal sufficient snippets** +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-midterm_2024-18-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q17 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `17` +- Topic: final-dictionary-2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What will be printed by the following program? + +**Options** +- `a`: True +- `b`: False +- `c`: An error message +- `d`: None + +**Correct answer:** `a` + +**Official explanation:** Dictionary equality compares key-value contents rather than insertion order. Since both dictionaries contain the same pairs, the comparison prints True. + +**Why not certain:** None of the provided snippets explain that dictionary equality (`==`) in Python compares the content (key-value pairs) regardless of the order in which they were defined. A student with zero knowledge would likely guess based on the numbers being the same, but wouldn't know for certain if order matters in Python collections. + +**Gap summary:** The snippets identify dictionaries but fail to explain the 'unordered' nature of standard dictionary comparison. + +**Missing concepts:** dictionary equality comparison; order-insensitivity of dictionary contents for == +**Suggested fix:** Add a snippet or AI question that specifically addresses how Python compares dictionaries vs lists (where order does matter). + +**Best snippet** +- `exam-trial_midterm-10-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are. + +**Top 3 snippets** +- `exam-trial_midterm-10-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are. +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] + Why: Contains a reference to a dictionary ('characters') and mentions checking if methods mutate lists in place, providing some context that dictionaries involve keys and values. + +**Minimal sufficient snippets** +- `exam-trial_midterm-10-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows the `{}` syntax for dictionaries. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q18 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `18` +- Topic: final-dictionary-3 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +d1 = {1: 2, 2: 1} + +The following code segments all print exactly the same output, except for one. Which one? + +**Options** +- `a`: result = 1 +for x in d1.values(): + result *= x +print(result) +- `b`: result = -1 +for x in d1.keys(): + result += d1[x] +print(result) +- `c`: result = 4 +for x in d1.items(): + result = result // x[1] +print(result) +- `d`: result = -4 +for x in d1: + result /= d1[x] +print(result) + +**Correct answer:** `d` + +**Official explanation:** A, B, and C all print 2. Option D uses true division starting from -4, so it prints -2.0 instead, making it the odd one out. + +**Why not certain:** The snippets do not define '.values()', '.keys()', or '.items()', nor do they explain that '.items()' yields tuples where indexing (x[1]) is required. Crucially, there is no explanation of the difference between true division (/) and floor division (//), which is the primary reason Option D is the odd one out (producing a float). + +**Gap summary:** Missing definitions for dictionary iteration methods and the semantic difference between division operators. + +**Missing concepts:** dict.values(); dict.keys(); dict.items(); Tuple indexing in loops (x[1]); True division (/) vs Floor division (//) +**Suggested fix:** Add a reference item covering dictionary iteration methods and a section on arithmetic operators highlighting float vs int outputs. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D. +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Provides a basic example of dictionary structure and calculation, though it lacks the specific methods (.values, .items) needed for this question. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q19 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `19` +- Topic: final-functions-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose that you have a string called s1, which contains several letters. The letter "x" and the letter "y" occur exactly once in the string, and "x" always precedes "y". + +You'd like to print out a string that looks just like s1, except that the letters "x" and "y" should be swapped. + +For example, if: +s1 = "axbyc" +then you'd like to print: +aybxc + +Reminder: The replace string method has a third argument, which allows you to specify the maximum number of replacements you want to make, counting from left to right. + +**Options** +- `a`: s1 = s1.replace('x', 'y', 1).replace('y', 'x', 1) +print(s1) +- `b`: s1 = s1.replace('y', 'x', 1).replace('x', 'y', 1) +print(s1) +- `c`: s1.replace('x', 'y', 1).replace('y', 'x', 1) +print(s1) +- `d`: s1.replace('y', 'x', 1).replace('x', 'y', 1) +print(s1) + +**Correct answer:** `b` + +**Official explanation:** Option B first changes the single y to x, then changes the first x from left to right back to y, which swaps the two letters. Options C and D do not assign the new string back to s1, and A changes the first replacement back incorrectly. + +**Why not certain:** None of the snippets explain string immutability (the fact that .replace() returns a NEW string and does not modify the original). Without this knowledge, a student cannot distinguish between Options A/B and C/D. Additionally, there is no explanation of the left-to-right execution of chained .replace() calls, which is necessary to understand why B is correct and A is not. + +**Gap summary:** The provided snippets focus on slicing, lists, and OOP, completely missing string method mechanics and the concept of immutability. + +**Missing concepts:** String Immutability (methods return new strings; they don't mutate in place); str.replace() behavior and argument order; Method Chaining execution order (left-to-right) +**Suggested fix:** Add a snippet specifically for 'String Immutability' and 'The .replace() method' showing that s.replace() requires s = s.replace() to save changes. + +**Best snippet** +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + Why: This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic. + +**Top 3 snippets** +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + Why: This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'Return Behavior' piece explains that functions return values (or None) and needs to be captured, which is helpful for understanding why Options C and D (which lack assignment) are incorrect. + +**Minimal sufficient snippets** +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] +- `aiq-4`: Comprehensions [w6-comprehensions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q22 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `22` +- Topic: List lambda 2 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Assume that you have a variable called x, which contains a list of integers. + +Which of the following code segments will create another list that has every element of x multiplied by 2? + +For example, if +x = [1, 2, 3, 4, 5] +then which of the following code segments will result in the list: +[2, 4, 6, 8, 10] + +**Options** +- `a`: list(map(lambda i : i * 2, x)) +- `b`: [(lambda i : i * 2)(item) for item in x] +- `c`: y = lambda i : i * 2 +[y(i) for i in x] +- `d`: All three code segments would work as intended + +**Correct answer:** `d` + +**Official explanation:** Each option constructs the doubled list correctly: `map` with a lambda, an immediately called lambda inside a list comprehension, and a named lambda used inside a list comprehension all apply `i * 2` to every element of `x`. + +**Why not certain:** The candidate snippets completely lack an explanation of 'lambda' (anonymous functions) and 'list comprehensions', which are the two most critical concepts required to evaluate the code segments in this question. + +**Gap summary:** There is a complete absence of documentation for functional programming primitives (lambda, map) and Pythonic iteration (list comprehensions) in the provided candidates. + +**Missing concepts:** lambda syntax (lambda arguments : expression); built-in Python map() function; list comprehension syntax [expr for item in iterable]; immediately called lambda expressions +**Suggested fix:** Add a 'Functional Programming and Comprehensions' snippet that covers lambda definitions, the built-in map() function, and the transformation pattern in list comprehensions. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a). + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a). +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Demonstrates the 'list()' constructor being used to wrap an iterable, which helps explain the structure of the code in option (a). + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q23 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `23` +- Topic: List logic 2 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Which of the following programs creates a new list y, in which the elements are those elements of list x that are equal to their indices? +You can assume x consists of unique integers. + +For example, if: +x = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10] +then the program should create a new list y such that: +y = [0, 3, 6, 7, 8, 10] + +**Options** +- `a`: y = [] +for i, j in enumerate(x): + if i == j: + y.append(i) +- `b`: y = [] +for i, j in enumerate(x): + if i == j: + y.append(j) +- `c`: y = [i for i in x if i == x.index(i)] +- `d`: All three programs would work as intended + +**Correct answer:** `d` + +**Official explanation:** In A and B, whenever `i == j`, appending either `i` or `j` gives the same value because the index equals the element. In C, `x.index(i)` returns the position of `i`, so the comprehension keeps exactly the elements equal to their indices. Therefore all three programs work. + +**Why not certain:** None of the provided snippets explain 'enumerate()', list comprehensions for filtering, or the 'list.index()' method. Without knowing how 'enumerate' unpacks into an index and a value, a student with zero prior knowledge cannot distinguish between options A, B, and C. + +**Gap summary:** There is a total lack of foundational list manipulation and iteration utilities in the candidate pool. + +**Missing concepts:** enumerate() usage for index/value pairs; List comprehension syntax for filtering; list.index(item) method behavior +**Suggested fix:** Create a new snippet specifically covering 'List Iteration and Filtering' that demonstrates enumerate and basic comprehensions. + +**Best snippet** +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality. + +**Top 3 snippets** +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Although it uses Pandas, it discusses using a 'boolean mask on the index' to select specific elements, which introduces the student to the concept of index-based selection logic. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Describes a transformation where elements are compared to a 'mean of the elements', reinforcing the pattern of evaluating list/series values against a common property. + +**Minimal sufficient snippets** +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q24 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `24` +- Topic: List loop 2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Assume that you have a list called x, which is a list of multiple sub-lists containing integers. + +Which of the following programs will create a new list y that is equal to the sub-list of x whose sum of elements is the highest? + +You can assume that the sum of elements in each sub-list is a different number, so that there is only one that is the highest. + +For example, if: +x = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]] +then y should be: +y = [8, 20, 300] + +**Options** +- `a`: y = max(x) +- `b`: z = [] +for i in x: + z.append(sum(i)) +y = x[z.index(max(z))] +- `c`: x.sort() +y = x[-1] +- `d`: y = [i for i in x if sum(i) == max(x)] + +**Correct answer:** `b` + +**Official explanation:** Option B computes the sum of each sub-list, finds the position of the largest sum, and then returns the corresponding original sub-list. The other options compare lists lexicographically or compare a numeric sum against `max(x)`, which is a list. + +**Why not certain:** The snippets fail to define the 'sum()' function, the 'max()' function, and the 'list.index()' method, all of which are essential to understanding the correct option (B). Furthermore, there is no explanation of lexicographical comparison, which is necessary to understand why 'max(x)' in options A and D compares the first elements of the sub-lists rather than their sums. + +**Gap summary:** The student lacks definitions for the core built-in functions (sum, max) and list methods (index) used in the logic, as well as the concept of list-of-lists comparison behavior. + +**Missing concepts:** sum() function on lists; max() function on lists of integers; list.index() method; Lexicographical comparison of lists (how max() works on a list of lists) +**Suggested fix:** Add a snippet explicitly covering 'Aggregations and Search' that defines sum(), max(), and .index(), and another piece clarifying that max([[100], [200, 1]]) compares the first elements (100 vs 200) rather than the total count or sum. + +**Best snippet** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items. + +**Top 3 snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items. +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + Why: Includes examples of list methods like .append(), which is used in the correct answer's loop to build the helper list. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: Provides a hint about list properties and equality (e.g., [1,2]==[2,1] is False), though it lacks specific lexicographical comparison details. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q01 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `1` +- Topic: 1_Basics_Logic_2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination. + +You want to write a program to advice Dutch residents on the documents they need to prepare before traveling: +- If they travel within Europe, your program should print "No passport needed. Bring your ID card." +- If they travel outside of Europe, the program should print "Please bring your passport." + +Which of the following code segment will achieve what you need? + +**Options** +- `a`: if destination in europe: + print('No passport needed. Bring your ID card.') +else: + print('Please bring your passport.') +- `b`: if destination in europe: + return 'No passport needed. Bring your ID card.' +elif destination not in europe: + return 'Please bring your passport.' +- `c`: for country in europe: + if destination = country: + print('No passport needed. Bring your ID card.') + else: + print('Please bring your passport.') +- `d`: for country in europe: + if destination != country: + return 'Please bring your passport.' + else: + return 'No passport needed. Bring your ID card.' + +**Correct answer:** `a` + +**Official explanation:** Option A directly checks whether destination is in the list of European countries and prints the correct message in each case. The other options either use the wrong control flow or invalid syntax. + +**Why not certain:** Excluding the identical past exam piece, there is no snippet provided that explains the 'in' operator for membership testing or the basic 'if-else' control flow syntax. While 'aiq-4' helps eliminate 'return' options, the student cannot distinguish between the correct 'in' check and the logically flawed 'for' loop in option (c). + +**Gap summary:** The snippets fail to explain membership operators and basic conditional logic outside of a function context. + +**Missing concepts:** Membership operators (in, not in); Basic if-else syntax; Comparison (==) vs Assignment (=) +**Suggested fix:** Add a foundational snippet covering membership testing in lists/strings and basic if-else blocks that use print statements. + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here. + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here. +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Shows a list-based scenario where the goal is to print formatted strings, reinforcing the use of print() over return. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why excluded: This piece contains the exact text and logic of the current question, providing the answer directly. + +### final-exam-study-guide-trial-python-basics-2023-q06 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `6` +- Topic: 2-dictionaries - slicing - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have the following dictionary that represents the monthly sales of a store: +monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800} + +You need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended? + +**Options** +- `a`: sales_subset = [monthly_sales[key] for key in list(monthly_sales.keys())[:3]] +average_sales = sum(sales_subset) / len(sales_subset) +print(average_sales) +- `b`: sales_subset = monthly_sales[:3] +average_sales = sum(sales_subset) / len(sales_subset) +print(average_sales) +- `c`: sales_subset = list(monthly_sales.items())[:3] +average_sales = sum(sales_subset) / len(sales_subset) +print(average_sales) +- `d`: sales_subset = monthly_sales['January':'March'] +average_sales = sum(sales_subset.values()) / len(sales_subset) +print(average_sales) + +**Correct answer:** `a` + +**Official explanation:** Option A first collects the values for the first three keys into a list and then computes the average correctly. The other options attempt unsupported dictionary slicing or try to sum tuples instead of numeric values. + +**Why not certain:** Excluding the identical past exam piece, none of the snippets explain that dictionaries are unsliceable or how to correctly use list(d.keys())[:3] to get a subset of values. A student wouldn't know why options B, C, or D fail. + +**Gap summary:** The snippets fail to address the core concept of the question: dictionary slicing limitations and the workaround using list conversion of keys. + +**Missing concepts:** dictionaries do not support slicing (dict[:n]); slicing list(dict.keys()) to extract specific entries; dictionary .items() returns tuples, which cannot be summed directly +**Suggested fix:** Add a summary snippet or lecture piece explicitly stating that dictionaries cannot be sliced like lists and demonstrating the list(d.keys())[:n] pattern. + +**Best snippet** +- `exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question. + +**Top 3 snippets** +- `exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question. +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Shows the concept of summing values from a set of keyword arguments (which act like a dictionary). + +**Minimal sufficient snippets** +- `exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why excluded: This is the exact same question as the one being evaluated, providing the correct answer directly. + +### final-exam-study-guide-trial-python-basics-2023-q13 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `13` +- Topic: 6-string - fstring - 2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have the following objects loaded in Python: +item = "laptop" +price = 1299.99 + +You need to print the following sentence: +The laptop is priced at $1299.99. + +Which of the following lines of code works as intended? + +**Options** +- `a`: message = "The {0} is priced at ${1}.".format(item, price) +print(message) +- `b`: message = "The {0} is priced at ${1}.".format(item, price) +print(mesage) +- `c`: message = "The {item} costs ${price}.".format(price, item) +print(message) +- `d`: message = "The {item} costs ${price}.".format(price, item) +print(message) + +**Correct answer:** `a` + +**Official explanation:** Option A correctly uses positional placeholders and prints the defined variable `message`. Option B appears to use a misspelled variable name in the print call, and C/D mix named placeholders with positional arguments. + +**Why not certain:** None of the candidate snippets cover string formatting techniques such as f-strings or the .format() method. The question specifically tests positional placeholders ({0}, {1}) and argument mapping in .format(), as well as recognizing variable name typos. The provided snippets focus on dictionaries, lists, and function arguments (**kwargs), which are unrelated. + +**Gap summary:** Complete absence of documentation regarding string formatting and interpolation. + +**Missing concepts:** The .format() method syntax; Positional placeholders ({0}, {1}) in strings; Argument mapping order in .format(); Basic variable name matching and typo detection +**Suggested fix:** Add a foundational snippet (from Week 1 or 2) that explicitly demonstrates f-strings and the .format() method, including how indices map to arguments. + +**Best snippet** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question. + +**Top 3 snippets** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question. +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Mentions a specific string format (for a URL), but relates to the data format rather than the Python .format() method. + +**Minimal sufficient snippets** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows a basic print statement; however, it provides no help with the actual core of the question (string formatting). + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q14 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `14` +- Topic: 7-pandas - easy - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have run the following block of code: + +import pandas as pd +data = {'A': [1, 2, 3], + 'B': [4, 5, 6], + 'C': [7, 8, 9]} +df = pd.DataFrame(data) + +Which of the following lines of code give(s) the following output? +1 4 +2 5 +3 6 +Name: B, dtype: int64 + +**Options** +- `a`: df.loc[:, 'B'] +- `b`: df['B'].loc[:] +- `c`: df['B'] +- `d`: All of the given lines. + +**Correct answer:** `d` + +**Official explanation:** Each of A, B, and C selects the same Series containing column `B`, so the correct choice is that all listed lines produce the shown output. + +**Why not certain:** While the snippets show examples of column access (df['A']) and filtered access (df.loc[...]), they do not explicitly teach the equivalence of df['B'], df.loc[:, 'B'], and df['B'].loc[:]. A student without prior knowledge would likely recognize df['B'] but would not have enough information to confirm that the other two syntaxes produce the exact same result. + +**Gap summary:** Missing a clear explanation of pandas indexing equivalence rules for Series selection. + +**Missing concepts:** Equivalence of bracket notation (df['col']) and .loc for column selection (df.loc[:, 'col']); Understanding that .loc[:] on a Series is a redundant/identity operation; Fundamental difference between selecting a Series (column) and a DataFrame (subset) +**Suggested fix:** Add a foundational Pandas snippet specifically illustrating 'Equivalent Selection Methods' for columns, showing that basic brackets, .loc with a colon, and chained identity slices all return the same Series. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: This snippet involves creating columns based on existing ones, which likely demonstrates the df['col'] syntax used in option C. +- `exam-intro_python_sample_final_24_25-7-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: Mentions keeping specific columns when creating a new DataFrame, reinforcing the concept of column selection. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q15 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `15` +- Topic: 8_Datetime_Easy_1 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Which code segment gives the same output as the following? + +date = datetime.strptime("05.12.2023", "%m.%d.%Y") +print((date + timedelta(days=-10)).strftime("%d-%m-%Y")) + +You may assume that datetime and timedelta classess are already imported from the datetime module. + +**Options** +- `a`: print(datetime.strptime('22-05-2023', '%d.%m.%Y')) +- `b`: print('02-05-2023') +- `c`: print(datetime.strptime('05.22.2023', '%d-%m-%Y')) +- `d`: date = datetime.strptime('10/05/2023', '%d/%m/%Y') +print((date + timedelta(days=5)).strftime('%m-%d-%Y')) + +**Correct answer:** `b` + +**Official explanation:** The original code parses May 12, 2023 and subtracts 10 days, so the printed result is the string `02-05-2023`. + +**Why not certain:** A student with zero Python knowledge cannot determine the output without knowing what the format codes '%m', '%d', and '%Y' represent. Specifically, they cannot know if '05.12' is May 12 or December 5, nor can they know how timedelta(days=-10) behaves without explicit documentation of those parameters. + +**Gap summary:** Existing snippets mention the existence of the Datetime module but do not define the specific syntax for parsing/formatting dates or the available attributes for timedelta initialization. + +**Missing concepts:** datetime.strptime and datetime.strftime format codes (%d, %m, %Y); Initialization parameters for timedelta (e.g., days=X) +**Suggested fix:** Add a lecture-based or reference snippet that defines common strftime/strptime format codes and provides a basic example of date arithmetic using timedelta. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic. +- `ks-b6a39f66a2`: Functions and Imports [w1-functions-and-imports] + Why: Provides the fundamental definition of the print function, which is necessary to understand that the code's purpose is to output a specific string to the screen. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] +- `ks-b6a39f66a2`: Functions and Imports [w1-functions-and-imports] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q18 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `18` +- Topic: 6-strings - find & replace - 1 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Consider the following line of code: + +text = "The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising." + +You want to create a new string called new_text where all occurances of "oil" are replaced by "natural gas". + +So: +print(new_text) +should return: +"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising." + +Which of the following code segments achieve(s) what you want? + +**Options** +- `a`: new_text = ' '.join([word if word != 'oil' else 'natural gas' for word in text.split()]) +- `b`: new_text = text.replace("oil", "natural gas") +- `c`: new_text = text.split() +for index, word in enumerate(new_text): + if word == 'oil': + new_text[index] = 'natural gas' +new_text = ' '.join(new_text) +- `d`: All of the given options works as intended. + +**Correct answer:** `d` + +**Official explanation:** All three code fragments replace each occurrence of the standalone word `oil` with `natural gas`, so the correct answer is that all of them achieve the requested result. + +**Why not certain:** The candidate snippets focus on dictionaries, functions, and Pandas. There is zero mention of the .replace(), .split(), or .join() string methods, nor is there an explanation of list comprehensions or the enumerate() function, all of which are critical to evaluating the four options. + +**Gap summary:** The knowledge base is missing foundational string manipulation methods and advanced iteration patterns (list comprehensions). + +**Missing concepts:** str.replace(old, new) method; str.split() method for breaking strings into words; ' '.join(list) method for combining words; List comprehensions with if-else logic; enumerate() for tracking list indices during iteration +**Suggested fix:** Add a dedicated snippet family for 'String Methods' and another for 'Iterables and List Comprehensions' containing examples of find/replace patterns. + +**Best snippet** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic. +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Involves string formatting and character separation, providing a basic context for string-based function arguments. +- `exam-Test Exam 07-06-22-4-w2-conditions`: Conditions [w2-conditions] + Why: Involves checking string properties (anagrams), which relates to the conditional logic used in option 'a' and 'c' of the question. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q19 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `19` +- Topic: 7-pandas - hard - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Consider the following pandas DataFrame called df: + + Name Age Gender Salary +0 John 25 Male 50000 +1 Jane 30 Female 65000 +2 Alex 35 Male 80000 +3 Lisa 40 Female 70000 +4 Mark 28 Male 55000 + +You need to perform a series of operations on this DataFrame. +- Operation 1: Select all rows where the age is greater than 30 and the gender is "Male". +- Operation 2: Create a new column called Sex_abbr of which the values should be "F" if gender is "Female" and "M" if gender is "Male". +- Operation 3: Calculate the average salary of all employees. + +Which of the following blocks of code performs these operations as intended? + +**Options** +- `a`: df_operation1 = df[(df['Age'] > 30) & (df['Gender'] == 'Male')] +df['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']] +df_operation3 = df['Salary'].mean() +- `b`: df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male') +df['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']] +df_operation3 = df['Salary'].mean() +- `c`: df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male') +df['Sex_abbr'] = df['Gender'].map(lambda x: 'M' if x == 'Male' else 'F') +df_operation3 = df['Salary'].sum()/len(df) +- `d`: df_operation1 = df[df['Age'] > 30 & df['Gender'] == 'Male'] +df['Sex_abbr'].map(lambda x: 'M' if x == 'Male' else 'F' for x in df['Gender']) +df_operation3 = df['Salary'].sum()/len(df) + +**Correct answer:** `a` + +**Official explanation:** Option A correctly filters rows with both conditions using boolean masking, builds the abbreviation column from the Gender column, and computes the average salary with mean(). + +**Why not certain:** The snippets provide the high-level concepts (column creation, boolean masks, mean) but fail to show the specific syntax required for 'hard' pandas operations: 1) The use of bitwise '&' with mandatory parentheses for multiple filter conditions, and 2) The syntax for list comprehensions or lambda mapping used to derive new column values. A zero-knowledge student could guess based on keywords but wouldn't know why option 'a' is syntactically superior to 'd' (operator precedence) or 'b/c' (accessor syntax). + +**Gap summary:** Critical syntax for multi-condition filtering and conditional column creation is missing. + +**Missing concepts:** Pandas multi-condition boolean masking (using '&' and '|' with required parentheses); Derived column creation using list comprehensions with if/else (ternary) logic; Correct accessor syntax for .loc vs standard brackets [] +**Suggested fix:** Add a new snippet covering complex pandas selections and transformations. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Mentions 'boolean mask', providing a conceptual link to row selection (Operation 1), though it lacks the specific syntax for multiple conditions. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Mentions calculating the 'mean' of a pandas Series, which is the direct requirement for Operation 3. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q20 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `20` +- Topic: 7-pandas - lambda - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Consider the following pandas DataFrame called df: + + Name Performance_review Salary +0 John 2 50000 +1 Jane 4 65000 +2 Alex 3 80000 +3 Lisa 2 70000 +4 Mark 1 55000 + +You want to create a new column called Bonus that compute each employee's bonus based on their salary and performance review using the following formula: +- if the performance review is less than 4, the bonus is 0. +- if the performance review is 4 or 5, the bonus is 5% of the salary. + +Which of the following code snippets works as intended? + +**Options** +- `a`: df['Bonus'] = df.apply(lambda row: row['Salary']*0.05 if row['Performance_review']>=4 else 0, axis=1) +- `b`: df['Bonus'] = df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>=4 else 0) +- `c`: df['Bonus'] = map(df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>4 else 0)) +- `d`: df['Bonus'] = df['Salary'].map(lambda row: row*0.05 if df['Performance_review']>=4 else 0) + +**Correct answer:** `a` + +**Official explanation:** Option A evaluates each row, checks the row's Performance_review value, and returns either 5% of Salary or 0 for that employee. + +**Why not certain:** While the snippets cover basic column creation and the concept of mapping functions, they do not explain the 'axis=1' parameter or the specific 'lambda row' pattern required to access multiple columns at once. A student with zero prior knowledge would likely struggle to distinguish between using .apply() on the DataFrame vs. using .map() or .apply() on a single column. + +**Gap summary:** There is no information explaining row-wise operations involving multiple columns, specifically the 'axis=1' parameter in .apply(). + +**Missing concepts:** df.apply(axis=1) for row-wise manipulation; Using lambda row to access multiple column values simultaneously; Difference between Series.map() and DataFrame.apply(axis=1) +**Suggested fix:** Add a snippet to Week 5 (Pandas) that explicitly shows how to calculate a new column based on conditions across two or more other columns using .apply(axis=1). + +**Best snippet** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context. +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Demonstrates the fundamental syntax for creating a new column ('C') in a DataFrame from existing columns ('A' and 'B'), which helps a student understand the 'df['Bonus'] = ...' structure. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q21 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `21` +- Topic: 8_Datetime_Function_3 +- Status: **insufficient** +- Confidence: `medium` + +**Question** + +You want to create a function called main which take an integer and a flexible number of strings as arguments. The strings represent dates in the format of DD MM YYYY. The day, month and year can be separated by different characters. + +Your function should look for the string inputs which represent dates as DD-MM-YYYY or DD/MM/YYYY and return those strings in the format of DD.MM.YYYY in a list. Furthermore, the dates represented by the strings should be shifted by the amount of days as given by the integer argument. + +For example, if we call your function as: +main(3, '25/06/2003', '26.06.2003', '27-06-2003', '28:06:2023', '29-06-2023', '30.06.2023') + +the output should be: +['28.06.2003', '30.06.2003', '02.07.2023'] + +Take a look at the following code segment. Does it do what is intended? If not, then why not? + +**Options** +- `a`: The code segment works as intended. +- `b`: This code segment does not work because the function will return a list of datetime objects, not a list of strings representing dates. +- `c`: This code segment does not work because the strftime() method cannot be applied to NoneType object. +- `d`: This code segment produces an error because you cannot concatenate strings and timedelta. + +**Correct answer:** `b` + +**Official explanation:** The function parses matching inputs and adds the day offset, but it appends datetime objects and never converts them back to strings in DD.MM.YYYY format before returning. + +**Why not certain:** The snippets explain function syntax and flexible arguments (*args), but there is zero information regarding the datetime module. A student with no prior knowledge wouldn't know that datetime.strptime returns an object or that timedelta addition results in another datetime object, which is the core of the question (distinguishing between objects and strings). + +**Gap summary:** Complete absence of datetime module documentation or usage examples. + +**Missing concepts:** datetime.strptime (parsing strings to datetime objects); datetime.strftime (formatting datetime objects to strings); timedelta (representing and adding time durations); Difference between datetime objects and string representations of dates +**Suggested fix:** Add a new snippet or key point explaining the datetime module workflow: String -> strptime -> Object -> arithmetic with timedelta -> strftime -> String. + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature. + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature. +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: Provides a practical example of a function using *args to filter and process a flexible number of inputs, mirroring the structure of the exam question. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q22 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `22` +- Topic: 8_Datetime_Hard_2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You want to define a class called Calendar, which has four attributes that are initialized at the time of object construction: +1. The 'event' attribute can be any string, +2. The 'date' attribute is a string representing a date as 'DD-MM-YYYY', +3. The 'start' attribute is a string representing the time as 'HH:MM', and +4. The 'length' attribute is an integer representing the amount of minutes. + +The class should also have a method called get_details() that gives a description of Calendar objects. + +For example, if we execute the following commands; +event1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20) +print(event1.get_details()) + +the output should be: +Coffee meeting: 01-06-2023, 9:30-9:50. + +Which of the following code segments gives you what you want? + +**Options** +- `a`: class Calendar(): + def __init__(self, event, date, start, length): + self.event = event + self.date = datetime.strptime(date, '%d-%m-%Y') + self.start = datetime(self.date.year, self.date.month, self.date.day, int(start.split(':')[0]), int(start.split(':')[1])) + self.end = self.start + timedelta(minutes=length) + def get_details(self): + return f'{self.event}: {self.date.strftime("%d-%m-%Y")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.' +- `b`: class Calendar(): + def __init__(self, event, date, start, length): + self.event = event + self.date = date + self.start = datetime(self.date, hour=start.split(':')[0], minute=start.split(':')[1]) + self.length = timedelta(minutes=length) + self.end = self.start + self.length + def get_details(self): + return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.' +- `c`: class Calendar(): + def __init__(self, event, date, start, length): + self.event = event + self.date = date + self.start = datetime(self.date, hour=start.hour, minute=start.minute) + self.end = self.self.start + timedelta(minutes=length) + def get_details(self): + return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.' +- `d`: class Calendar(): + def __init__(self, event, date, start, length): + self.event = event + self.date = datetime.strptime(date, '%d-%m-%Y') + self.start.hour = start.hour + self.start.minute = start.minute + self.end = self.start + timedelta(minutes=length) + def get_details(self): + return f'{self.event}: {self.date.strftime("%d-%m-%Y")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.' + +**Correct answer:** `a` + +**Official explanation:** Option A is the only choice that correctly parses the date string, combines the parsed date with the split start time to build a datetime, adds the duration in minutes, and formats the requested details string. + +**Why not certain:** While the snippets cover basic OOP and mention the existence of datetime/timedelta, they do not explain the strptime() and strftime() methods, nor how to instantiate a datetime object with specific hour/minute parameters or use split() on strings. A student with zero knowledge would not be able to confidently select Option A over the syntactically plausible but incorrect alternatives. + +**Gap summary:** The provided snippets lack coverage of datetime string parsing and formatting, and basic string splitting. + +**Missing concepts:** datetime.strptime(); datetime.strftime(); string.split(); timedelta(minutes=...); datetime object attribute access (.hour, .minute) +**Suggested fix:** Add a snippet family for Datetime Manipulation that explicitly shows parsing strings into datetimes, formatting them back to strings, and performing arithmetic with specific timedelta units (minutes, hours). + +**Best snippet** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides the basic syntax for class definitions and the __init__ method which is required to evaluate the structure of the options. +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Shows basic string formatting within a print/text context, which helps understanding the get_details() method structure. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q07 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `7` +- Topic: 2-list - comprehension - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What is the output of the following code segment? + +**Options** +- `a`: [2, 4] +- `b`: [3, 4, 5] +- `c`: [4] +- `d`: [] + +**Correct answer:** `c` + +**Official explanation:** The list comprehension keeps values x from [1, 2, 3, 4, 5] only when x is even and greater than 2. The only value satisfying both conditions is 4. + +**Why not certain:** Excluding the near-identical piece, there is no explanation of the specific Python 'list comprehension' syntax `[expression for item in iterable if condition]`. A student with zero knowledge would find the compact notation in the code context unintelligible based solely on the general snippets. + +**Gap summary:** The snippets lack a definition or syntax guide for list comprehensions and the modulo operator. + +**Missing concepts:** list comprehension syntax; modulo operator (%); Python logical 'and' in comprehensions +**Suggested fix:** Add a general-purpose snippet explaining list comprehension structure and common filtering patterns (like even/odd checks). + +**Best snippet** +- `exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why: Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension. + +**Top 3 snippets** +- `exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why: Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Briefly mentions the logic of finding 'even numbers', which helps decode the `x % 2 == 0` part of the code segment. + +**Minimal sufficient snippets** +- `exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names`: Objects and Names [w1-objects-and-names] +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-trial-final-exam-py22-7-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why excluded: This piece is an exact match for the question, providing the same code logic (filtering even numbers > 2) and the correct output '4'. + +### introduction-to-python-trial-final-exam-solutions-py22-q08 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `8` +- Topic: 2-list - manipulation - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What is the output of the following code segment? + +**Options** +- `a`: ['a', 'bb', 'ccc'] +- `b`: [1, 2, 3] +- `c`: [1, 'b', 3] +- `d`: ['aa', 'bb', 'cc'] + +**Correct answer:** `a` + +**Official explanation:** The loop iterates over pairs from zip(list1, list2) and multiplies each string by its matching integer, producing 'a', 'bb', and 'ccc'. + +**Why not certain:** While 'append' is covered, the core of the problem relies on two concepts completely missing from the candidates: 1) The zip() function pairing elements of lists together, and 2) String multiplication (e.g., 'a' * 2 = 'aa'). Without these, a student cannot determine the contents of the result list. + +**Gap summary:** Missing definitions for 'zip' and the behavior of the multiplication operator between integers and strings. + +**Missing concepts:** zip() function pairing; String-integer multiplication (repetition); Tuple/item indexing inside a loop +**Suggested fix:** Add a new snippet explaining zip(listA, listB) and a note that 'abc' * 2 results in 'abcabc'. + +**Best snippet** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code. + +**Top 3 snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code. +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + Why: Provides examples of various list methods and operations, helping the student understand list-based logic, though it lacks the specific 'zip' and 'string multiplication' concepts. + +**Minimal sufficient snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q09 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `9` +- Topic: 2-list - slicing - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have a list called mylist. You want to extract every fourth element starting from index 2 (inclusive) to the second-to-last index (inclusive) of that list using the following line of code: +subset = mylist[___:___:___] + +For example, if you have: +mylist = [10, 15, 20, 25, 30, 35, 40, 45, 50] + +then executing the following command: +print(subset) + +should print: +[20, 35] + +What should the blanks be filled with? + +**Options** +- `a`: 2:-1:3 +- `b`: 2:len(mylist)-1:3 +- `c`: Both of the given options are correct. +- `d`: None of the given options are correct. + +**Correct answer:** `c` + +**Official explanation:** Both stop values exclude the last element while starting at index 2 and stepping by 3, so both expressions return [20, 35] for the example list. + +**Why not certain:** While one snippet shows the `[start:stop:step]` syntax, it does not explain that the 'stop' index is exclusive, nor does it explain negative indexing (e.g., `-1`) or the `len()` function's role in indexing. A student with zero prior knowledge could not distinguish between options (a), (b), and (c) based on these snippets alone. + +**Gap summary:** The available snippets show the slicing syntax but omit the semantic rules required to solve the problem. + +**Missing concepts:** exclusive stop index in slicing; negative indexing (specifically -1 as the last element); relationship between len(list) and the last index; slicing step logic (Nth element vs step N-1) +**Suggested fix:** Add a foundational snippet about Python list slicing that explicitly defines the inclusive start, exclusive stop, and the behavior of the step parameter, including negative indices. + +**Best snippet** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question. + +**Top 3 snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question. +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Mentions operations on a 'list called x', which provides some context for list-based exam questions, though it does not cover slicing. + +**Minimal sufficient snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q10 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `10` +- Topic: 3_Function_Argument_2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following function, which takes a list of integers as an argument: + +What will be returned, if we call the function as follows: +main([0, 1, 2, 23, 24, 25]) + +**Options** +- `a`: 'abcxyz' +- `b`: ['a', 'b', 'c', 'x', 'y', 'z'] +- `c`: '012232425' +- `d`: None of the given options. + +**Correct answer:** `a` + +**Official explanation:** The function walks through the alphabet with enumerate and appends each character whose index is present in the input list, giving a, b, c, x, y, and z. + +**Why not certain:** The question's solution relies entirely on knowing that 'enumerate(alphabet)' yields pairs of (index, character). Without a snippet explaining that 'index' represents the numeric position (starting at 0), a student with zero prior knowledge cannot definitively solve the problem, as they wouldn't know if 'index' refers to the position or something else. + +**Gap summary:** There is no explanation of the 'enumerate' function or the concept of retrieving an index during a loop iteration. + +**Missing concepts:** enumerate() function; unpacking (index, value) in for loops; zero-based indexing +**Suggested fix:** Add a snippet explaining 'enumerate(sequence)': 'The enumerate() function allows you to loop through a sequence and have an automatic counter (index). Example: for i, val in enumerate(["A", "B"]): yields (0, "A") then (1, "B").' + +**Best snippet** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic. + +**Top 3 snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: Contains pieces on 'Return Behavior', which is essential for understanding that the function results in a single value rather than a side effect like printing. + +**Minimal sufficient snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Establishes the context of the alphabet string. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: Explains foundational return value mechanics. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q11 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `11` +- Topic: 3_Function_Built-in_1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have a variable called x which contains a string as follows: + +x = 'Hello world' + +Which of the following lines of code produce(s) 2 as an output? + +**Options** +- `a`: print(x.count('o')) +- `b`: print(x.split(' ')[0].count('ll')) +- `c`: print(len(x)//5) +- `d`: All of the given options. + +**Correct answer:** `d` + +**Official explanation:** The rendered solution page marks option D, indicating that the exam intends all three listed expressions to produce 2 for the given value of x. + +**Why not certain:** The candidate snippets are all past exam questions rather than documentation. None of them define the specific methods (.count, .split), the built-in function (len), or the floor division operator (//) required to verify the arithmetic in the options. A student with zero prior knowledge could not conclude that len('Hello world') // 5 equals 2 without knowing what len or // do. + +**Gap summary:** The snippets fail to provide definitions for core string methods and basic Python operators used in the question. + +**Missing concepts:** str.count(); str.split(); len() function; // (floor division operator) +**Suggested fix:** Add a foundational card covering 'Basic String Methods and Operators' that explicitly defines len(), .count(), .split(), and arithmetic operators like // and %. + +**Best snippet** +- `exam-trial_midterm-19-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question. + +**Top 3 snippets** +- `exam-trial_midterm-19-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question. +- `exam-Resit 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Shows a multiple-choice question structure where several expressions evaluate to the same result (True), leading to 'all lines' being correct, similar to the logic in the current question's Option D. +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Provides an example of string slicing and list conversion, which familiarizes the student with string-to-sequence operations like the .split() method in the question. + +**Minimal sufficient snippets** +- `exam-trial_midterm-19-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Resit 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q13 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `13` +- Topic: 6-string - fstring - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have the following objects loaded in Python: +name = "Alice" +age = 25 +country = "the USA" + +You need to print the following string: +My name is Alice. I am 25 years old, and I am from the USA. + +Which of the following lines of code works as intended? + +**Options** +- `a`: message = "My name is {0}. I am {2} years old, and I am from {1}.".format(name, country, age) +print(message) +- `b`: message = f"My name is {name}. I am {age} years old, and I am from {country}." +print(message) +- `c`: message = 'My name is ' + name + '. I am ' + str(age) + ' years old, and I am from ' + str(country) + '.' +print(message) +- `d`: All of the given options are correct. + +**Correct answer:** `d` + +**Official explanation:** All three code variants produce the target sentence: one uses format, one uses an f-string, and one uses string concatenation with str(age) and str(country). + +**Why not certain:** None of the candidate snippets demonstrate the syntax for f-strings, the .format() method, or string concatenation with type conversion (str()). The snippets are almost entirely focused on dictionaries and data structures (Week 2), while this question tests Week 1 string formatting fundamentals. + +**Gap summary:** The snippet database is missing fundamental content on string formatting and manipulation. + +**Missing concepts:** f-strings (syntax: f'...'); str.format() method (including positional indices like {0}, {1}); string concatenation (+) and the requirement to use str() for non-string objects +**Suggested fix:** Add a dedicated snippet family for 'String Formatting' that explicitly shows examples of f-strings, .format(), and concatenation side-by-side. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it. +- `exam-Trial final exam Introduction to Python-3-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why: This snippet establishes that names are strings, which helps a student identify the data types being manipulated in the question, though it doesn't help with the formatting syntax. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-Trial final exam Introduction to Python-3-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q14 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `14` +- Topic: 7-pandas - easy - 2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following DataFrame called df, and assume that pandas is already imported: + + Player Goals Assists +0 John 5 2 +1 Jane 3 6 +2 Alex 2 4 + +All of the following lines of code make the same selection, but one of the results has a different datatype. Which one? + +**Options** +- `a`: df.loc[:, 'Goals'] +- `b`: df['Goals'] +- `c`: df.loc[[0, 1, 2], 'Goals'] +- `d`: df.loc[:, ['Goals']] + +**Correct answer:** `d` + +**Official explanation:** The first three expressions return a Series, while selecting with a list of column names returns a one-column DataFrame instead. + +**Why not certain:** None of the provided snippets explain the crucial difference between selecting a column as a scalar (returning a Series) vs. selecting with a list (returning a DataFrame). The snippets show DataFrame usage but not the specific syntax/datatype rules required to answer 'Which one has a different datatype?'. + +**Gap summary:** The snippets identify pandas structures but fail to provide the rules for selection return types. + +**Missing concepts:** Difference between Series and DataFrame return types in pandas selection; Behavior of .loc when passed a single label vs a list of labels; The use of double brackets [[]] vs single brackets [] for column selection +**Suggested fix:** Add a summary item or a detailed lecture snippet that explicitly states: 'Selecting with a single label (df['A'] or df.loc[:, 'A']) returns a Series, while selecting with a list of labels (df[['A']] or df.loc[:, ['A']]) returns a DataFrame.' + +**Best snippet** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows a standard DataFrame with columns 'A' and 'B', helping the student visualize the structure mentioned in the question. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Mentions a 'pandas Series', which is one of the datatypes involved in the question options. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q17 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `17` +- Topic: 6-string - operations - 1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Consider the following code snippet. Which operation in the code snippet contains an error? + +**Options** +- `a`: Operation 1 +- `b`: Operation 2 +- `c`: Operation 3 +- `d`: None of the operations contains an error. + +**Correct answer:** `b` + +**Official explanation:** Operation 2 is incorrect because join should be called as the separator string's method with a single iterable argument, for example '-'.join(word_list). + +**Why not certain:** The snippets help rule out Operation 1 (slicing/append) and Operation 3 (replace), but none of the provided candidates describe the syntax or argument requirements for the .join() method. The error in Operation 2 is specifically about passing two arguments to .join() instead of one iterable; without a snippet defining .join()'s signature, a student cannot definitively identify this error. + +**Gap summary:** Missing documentation or examples for the string .join() and .split() methods, specifically their parameter signatures. + +**Missing concepts:** str.join() argument signature; str.split() behavior +**Suggested fix:** Add a reference snippet for common string methods that explicitly shows '.join(iterable)' taking exactly one argument. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-4-w2-conditions`: String Operations and Methods [w4-string-operations-and-methods] + Why: This snippet is categorized under 'String Operations and Methods' and explicitly discusses the .replace() method, which helps a student verify that Operation 3 in the question is likely correct. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-4-w2-conditions`: String Operations and Methods [w4-string-operations-and-methods] + Why: This snippet is categorized under 'String Operations and Methods' and explicitly discusses the .replace() method, which helps a student verify that Operation 3 in the question is likely correct. +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Shows string slicing syntax ([1::2]) and mentions reversing, which provides context for the reversing slice [::-1] used in Operation 1. +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Validates that .append() is a standard method for adding items to a list, which supports the logic in Operation 1. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-4-w2-conditions`: String Operations and Methods [w4-string-operations-and-methods] +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q18 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `18` +- Topic: 6-strings - find - 2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following variables called sentence1 and sentence2 which contain strings. The sentences contain names, but they are not properly capitalized. You want to create a new string object called paragraph, with the proper nouns capitalized in the two sentences and the two sentences connected into one big string. + +That is, if we execute the following line of code: +print(paragraph) +the output should be: +"Harry, Ron, and Hermione walked through the halls of Hogwarts; their footsteps echoing off the stone walls. +The Marauder's map in Harry's hands revealed the secret passageways and hidden rooms of the castle." + +Which of the following code segments achieves what you want? + +**Options** +- `a`: names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder'] +for name in names: + sentence1[sentence1.find(name)] = name.capitalize() + sentence2[sentence2.find(name)] = name.capitalize() +paragraph = sentence1 + " " + sentence2 +- `b`: names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder'] +for word, name in zip(sentence1, names): + if word == name: + sentence1 = sentence1.replace(word, name.capitalize()) +for word, name in zip(sentence2, names): + if word == name: + sentence2 = sentence2.replace(word, name.capitalize()) +paragraph = sentence1 + " " + sentence2 +- `c`: names = ['harry', 'ron', 'hermione', 'hogwarts', 'marauder'] +new1 = ' '.join([word.capitalize() if word in names else word for word in sentence1]) +new2 = ' '.join([word.capitalize() if word in names else word for word in sentence2]) +paragraph = new1 + " " + new2 +- `d`: for word in ['harry', 'ron', 'hermione', 'hogwarts', 'marauder']: + sentence1 = sentence1.replace(word, word.capitalize()) + sentence2 = sentence2.replace(word, word.capitalize()) +paragraph = sentence1 + " " + sentence2 + +**Correct answer:** `d` + +**Official explanation:** Option D correctly replaces each lowercase proper noun with its capitalized version in both strings and then concatenates the two sentences into paragraph. + +**Why not certain:** None of the provided snippets explain the Python string methods '.replace()', '.capitalize()', or '.find()'. Furthermore, nothing explains string immutability (to reject option A) or how to concatenate strings with '+'. A student with zero knowledge would not be able to distinguish between the options based on these snippets. + +**Gap summary:** The candidate snippets are almost entirely focused on Dictionaries and OOP, whereas the question is purely about String manipulation methods and Immutability. + +**Missing concepts:** string.replace(); string.capitalize(); string.find(); string immutability (cannot assign to index); string concatenation with + +**Suggested fix:** Add a documentation-style snippet or an example snippet from Week 6 (Strings) that demonstrates these specific methods and mentions that strings cannot be modified in-place. + +**Best snippet** +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This is the only snippet that explicitly mentions strings and the concept of upper/lower case versions of letters, although it does not provide the mechanics of the methods needed. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This is the only snippet that explicitly mentions strings and the concept of upper/lower case versions of letters, although it does not provide the mechanics of the methods needed. +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Mentions strings and character manipulation (dashes), providing some context that strings can be processed as objects. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q21 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `21` +- Topic: 8_Datetime_Function_2 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have the following definition for a class called Calendar. + +The method check_overlap() should return True if there are two overlapping events and False if the two events are not overlapping. + +For example, if we have the following Calendar objects: +event1 = Calendar('Coffee meeting', '01-06-2023 9:30', 20) +event2 = Calendar('Writing session', '01-06-2023 10:00', 150) +event3 = Calendar('Lunch meeting', '01-06-2023 12:00', 45) + +the following command should return False: +print(event1.check_overlap(event2)) + +and the following command returns True: +print(event2.check_overlap(event3)) + +Does the code segment given above do what you want? If not, then why not? + +Hint: +The timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration. + +**Options** +- `a`: The code segment works as intended. +- `b`: This code segment does not work because the condition provided after the return keyword is incorrect. +- `c`: This code segment does not work because the syntax to parse the input string to create a datetime object is incorrect. +- `d`: This code segment does not work because the __init__ method needs 4 parameters and only 3 arguments are passed. + +**Correct answer:** `a` + +**Official explanation:** The datetime format string matches the input values, timedelta(minutes=length) creates the correct end time, and the overlap condition correctly detects whether two intervals intersect. + +**Why not certain:** While the hint explains 'timedelta' conceptually, no snippet covers the 'datetime.strptime' syntax or the specific logic required for interval overlap (comparison of start/end times across objects). A student would not know if the date format string is correct or if the overlap condition is logically sound. + +**Gap summary:** The candidate snippets focus on basic OOP and data structures, completely missing the 'datetime' module and interval comparison logic. + +**Missing concepts:** datetime.strptime format codes; datetime arithmetic with timedelta; Interval overlap logic (A.start < B.end and A.end > B.start) +**Suggested fix:** Add a snippet family for 'Date and Time' that includes strptime examples and basic datetime comparisons. + +**Best snippet** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Shows how to define a method ('compare') that compares 'self' to 'other', which is the core structure of the 'check_overlap' method in the question. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Shows how to define a method ('compare') that compares 'self' to 'other', which is the core structure of the 'check_overlap' method in the question. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides context for class initialization and attribute assignment in the __init__ method, helping to evaluate option (d). + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q22 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `22` +- Topic: 8_Datetime_Hard_1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You want to create a DataFrame called df that has the following format: + + Day Month Year +01-01-23 1 1 2023 +08-01-23 8 1 2023 +15-01-23 15 1 2023 +22-01-23 22 1 2023 +29-01-23 29 1 2023 + +Which of the following code segments achieves what you want? + +You may assume that the datetime and timedelta classes are already imported from the datetime module, as well as the pandas module (via: import pandas as pd). + +Hint: +The timedelta functions contains the following parameters: days, seconds, microseconds, milliseconds, minutes, hours, and weeks. All the parameters are optional and 0 by default. The timedelta object that is created using this function represents a duration. + +**Options** +- `a`: dates = [(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)] +data = {'Day': [date.day for date in dates], + 'Month': [date.month for date in dates], + 'Year': [date.year for date in dates]} +df = pd.DataFrame(data, index=[date.strftime('%d-%m-%y') for date in dates]) +- `b`: dates = [(datetime(2023, 1, 1) + timedelta(days=7*i)).strftime('%d-%m-%y') for i in range(5)] +data = {'Day': [date.day for date in dates], + 'Month': [date.month for date in dates], + 'Year': [date.year for date in dates]} +df = pd.DataFrame(data, index=dates) +- `c`: day = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).day for i in range(5)]) +month = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).month for i in range(5)]) +year = pd.Series([(datetime(2023, 1, 1) + timedelta(weeks=1*i)).year for i in range(5)]) +df = pd.DataFrame(data=[day, month, year]) +- `d`: df = pd.DataFrame(index=[(datetime(2023, 1, 1) + timedelta(weeks=1*i)) for i in range(5)], + {'Day': [date.days for date in index], + 'Month': [date.months for date in index], + 'Year': [date.year for date in index]}) + +**Correct answer:** `a` + +**Official explanation:** Option A keeps real datetime objects long enough to derive day, month, year, and then formats those dates into the desired string index for the DataFrame. + +**Why not certain:** The provided snippets completely lack coverage of the 'datetime' module, 'timedelta' class, 'strftime' method, and the specific syntax for initializing a Pandas DataFrame with a manual index. + +**Gap summary:** The primary difficulty is the logic involving datetime object manipulation and formatting. + +**Missing concepts:** datetime module attributes (.day, .month, .year); timedelta parameter usage (weeks vs days); strftime() string formatting syntax; pd.DataFrame(data, index=...) parameter usage +**Suggested fix:** Add a snippet or key point piece explaining how to generate date ranges using timedelta and how to convert datetime objects to formatted strings. + +**Best snippet** +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows basic dictionary structure which is the basis for the 'data' variable used to construct the DataFrame in the options. + +**Top 3 snippets** +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows basic dictionary structure which is the basis for the 'data' variable used to construct the DataFrame in the options. +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Displays what a printed DataFrame looks like, helping the student visualize the goal (index and columns). + +**Minimal sufficient snippets** +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q01 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `1` +- Topic: Multiple choice - Question-ID: 357615 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Suppose you have a list called x containing tuples, where +x = [(1, 2), (3, 4), (5, 6), (7, 8)] + +Which of the following lines of code will print True? + +**Options** +- `a`: print(x[0][1] * x[-3][0] == x[2][1]) +- `b`: print(x[1][0] + x[-2][0] == x[-1][1]) +- `c`: print(x[-1][0] - x[-2][0] == x[0][1]) +- `d`: All lines of code will print True. + +**Correct answer:** `d` + +**Official explanation:** All three expressions evaluate to True: 2 * 3 = 6 equals x[2][1], 3 + 5 = 8 equals x[-1][1], and 7 - 5 = 2 equals x[0][1]. + +**Why not certain:** Beyond the near-identical past exam questions, there is no informational snippet explaining Python's zero-based indexing, negative indexing, or nested sequence access (e.g., list[i][j]). A student with zero knowledge would be unable to solve this logically with the provided non-identical snippets. + +**Gap summary:** The candidate list lacks foundational documentation for sequence indexing rules. + +**Missing concepts:** Zero-based indexing; Negative indexing (e.g., -1 is the last element); Nested indexing for lists containing tuples; Basic arithmetic/equality logic with indexed variables +**Suggested fix:** Add a foundational 'List and Tuple Indexing' topic card covering both positive/negative indices and nested access. + +**Best snippet** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This is the only remaining snippet that mentions lists and indexing (slicing), although it is insufficient for explaining nested indexing or negative indexing. + +**Top 3 snippets** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This is the only remaining snippet that mentions lists and indexing (slicing), although it is insufficient for explaining nested indexing or negative indexing. +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Mentions lists and basic operations, providing minimal additional context for list-related terminology. + +**Minimal sufficient snippets** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Provides the most relevant general context for lists among non-identical items. + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why excluded: This piece contains the exact same code context, question, and evaluates the options (A, B, and C) identically to the provided question JSON. +- `exam-Resit 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why excluded: Matches the question context perfectly and explicitly explains why all lines evaluate to True. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q03 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `3` +- Topic: Multiple choice - Question-ID: 355235 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +What will be printed by the following code segment? + +**Options** +- `a`: ['a', 'None', '123'] +- `b`: [[]] +- `c`: [] +- `d`: [None] + +**Correct answer:** `d` + +**Official explanation:** The code appends list-typed elements to `y`, but the return expression uses `append`, which itself returns `None`. The page marks option D as correct, so the intended evaluated output is `[None]`. + +**Why not certain:** The core trick of the question is that the 'append()' method returns 'None'. None of the snippets mention that list methods perform in-place modification and return None. A student using the snippets would likely understand the loop logic (filtering for lists) and incorrectly conclude the answer is [[]] (Option B) because they assume append returns the list it was called on. + +**Gap summary:** Missing a conceptual explanation that in-place list methods like append() return None. + +**Missing concepts:** The return value of the list.append() method is None. +**Suggested fix:** Add a snippet or detail rule explaining that methods that modify objects in-place (like append, sort, extend) return None. + +**Best snippet** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Explicitly demonstrates the .append() method on a list, which is the central operation in the question's return statement. + +**Top 3 snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Explicitly demonstrates the .append() method on a list, which is the central operation in the question's return statement. +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Helps a student understand the basic structure of a function that iterates through a list and conditionally appends to a new list, providing context for the first half of the code context. +- `exam-trial-final-exam-py22-3-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: Introduces the concept of 'None' being a specific return value/placeholder in Python functions. + +**Minimal sufficient snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] +- `exam-trial-final-exam-py22-3-w3-return-behavior`: Return Behavior [w3-return-behavior] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Resit 22/23-3-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why excluded: Uses the exact same loop logic (iterating through a list and checking if type(i) == type(x)) and input elements, although it focuses on a variant where the function returns the modified list 'y' rather than the result of the append call. +- `exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why excluded: Identical logic setup involving type checking and list filtering, but different return behavior statement. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q05 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `5` +- Topic: list slicing and sets +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have a list called x, where: +x = [1, 1, 2, 2, 3, 3, 4, 4, 5, 5] + +Which of the following code segments will print the following list? +[5, 4, 3, 2, 1] + +**Options** +- `a`: y = list(set(x)) +print(sorted(y, reverse = True)) +- `b`: print(x[::-2]) +- `c`: Both lines of code will print that output. +- `d`: Neither line of code will print that output. + +**Correct answer:** `c` + +**Official explanation:** Option A removes duplicates and sorts descending, which gives `[5, 4, 3, 2, 1]`. Option B takes every second element from the end of the symmetric list and also prints `[5, 4, 3, 2, 1]`. + +**Why not certain:** Without the near-identical past exam questions, the candidate snippets are insufficient. There is no general reference explaining that set() removes duplicates, how sorted() works with the reverse parameter, or how negative steps in slicing (like [::-2]) reverse the traversal order. + +**Gap summary:** The knowledge base lacks general reference material for sets, sorting parameters, and advanced slicing behavior. + +**Missing concepts:** set() function for removing duplicates; sorted() function with the reverse=True parameter; Slicing with negative steps (backwards traversal) +**Suggested fix:** Add a foundational reference snippet covering list/set conversions and advanced slicing mechanics. + +**Best snippet** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: This is the only non-identical snippet that demonstrates list slicing syntax (e.g., [1::2]), which is relevant to Option B, although it does not cover negative steps. + +**Top 3 snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: This is the only non-identical snippet that demonstrates list slicing syntax (e.g., [1::2]), which is relevant to Option B, although it does not cover negative steps. + +**Minimal sufficient snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Provides a baseline for understanding list indexing and slicing syntax. + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why excluded: This piece is an exact match for the question, containing the same list 'x', target output, and a detailed explanation of why Options A and B both work. +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why excluded: Virtually identical to the current question, providing the same code logic and a very clear explanation of the set() and sorting mechanics. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q10 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `10` +- Topic: String Methods +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What is the output of the following code segment? + +x = 'Hello, World!' +print([char for char in x if char.islower()]) + +**Options** +- `a`: ['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd'] +- `b`: ['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!'] +- `c`: ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'] +- `d`: ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd'] + +**Correct answer:** `a` + +**Official explanation:** The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower(). + +**Why not certain:** No snippet explains the 'islower()' method or the specific syntax of list comprehensions (the '[x for x in y if condition]' pattern). A student without prior knowledge would not know if 'islower()' returns true for spaces or punctuation, nor how the filter logic works. + +**Gap summary:** Missing explanations for list comprehension syntax and the .islower() string method. + +**Missing concepts:** List comprehensions with 'if' filters; String predicate methods (.islower, .isupper, .isdigit, .isalpha) +**Suggested fix:** Add a snippet explaining list comprehensions as a shorthand for 'create list, loop, if condition, append' and a reference for common string methods like .islower(). + +**Best snippet** +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] + Why: This family contains a piece on String Fundamentals (capitalize()) and Higher-Order Patterns (iterating transformations), which are the closest conceptual matches to string methods and list comprehensions. + +**Top 3 snippets** +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] + Why: This family contains a piece on String Fundamentals (capitalize()) and Higher-Order Patterns (iterating transformations), which are the closest conceptual matches to string methods and list comprehensions. +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Shows that a string can be converted to a list of characters using list() and slicing, which helps understand the structure of the expected output. +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Explicitly mentions 'lowercase vowels', providing a hint that 'lowercase' is a relevant category for character classification in the course. + +**Minimal sufficient snippets** +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q11 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `11` +- Topic: Functions and Imports +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What will be the output of the following code segment? + +list1 = [5, 10, 15, 20] +list2 = [2, 4, 6, 8] +result = [] + +for a, b in zip(list1, list2): + result.append(a // b) + +print(result) + +**Options** +- `a`: [1, 2, 3, 4] +- `b`: [2, 2, 2, 2] +- `c`: [6, 12, 18, 24] +- `d`: [2.5, 2.5, 2.5, 2.5] + +**Correct answer:** `b` + +**Official explanation:** The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2. + +**Why not certain:** The snippets do not explain the 'zip()' function or the floor division operator '//', which are critical to determining the output values (2 instead of 2.5). A student without prior knowledge would not know how 'a' and 'b' are paired or what '//' does. + +**Gap summary:** The candidate snippets cover basic list appending and printing but completely omit the 'zip' function and the '//' arithmetic operator. + +**Missing concepts:** zip() function for pairing elements; Floor division operator (//); Unpacking multiple variables in a for loop (for a, b in ...) +**Suggested fix:** Add a key point or AI example that explicitly demonstrates zip() and basic arithmetic operators like floor division. + +**Best snippet** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Shows basic list manipulation including 'append' and 'print', which are used in the question to build and display the result list. + +**Top 3 snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Shows basic list manipulation including 'append' and 'print', which are used in the question to build and display the result list. +- `ks-b6a39f66a2`: Functions and Imports [w1-functions-and-imports] + Why: Defines the 'print' function, helping a student understand that the final line of the code outputs the contents of 'result'. +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Demonstrates a 'for' loop that iterates through a list and uses 'append' to build a new list, mirroring the structure of the question. + +**Minimal sufficient snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] +- `ks-b6a39f66a2`: Functions and Imports [w1-functions-and-imports] +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q12 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `12` +- Topic: Sequences and Access +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. +Which of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]? + +**Options** +- `a`: subset = numbers[::-2][::-1] +- `b`: subset = numbers[-1::-2] +- `c`: subset = numbers[::-1][::2] +- `d`: subset = numbers[::-2] + +**Correct answer:** `a` + +**Official explanation:** A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2]. + +**Why not certain:** While one identical snippet exists, the remaining candidate snippets provide zero explanation of the 'start:stop:step' slicing syntax or how negative indices work. Without the identical piece, a student with no prior knowledge cannot solve this. + +**Gap summary:** The candidate set lacks any conceptual explanation of sequence slicing (step, start, stop). + +**Missing concepts:** List slicing syntax: list[start:stop:step]; Behavior of negative steps (e.g., ::-1 or ::-2); Behavior of negative start indices (e.g., -1); Chained slicing evaluation (e.g., [::-2][::-1]) +**Suggested fix:** Add a foundational reference item explaining list[start:stop:step] with specific examples for common patterns like reverse and skipping items. + +**Best snippet** +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Excluding the identical piece, this is the only snippet that touches on reversing a simple numeric list (turning [1, 2, 3, 4, 5] into [5, 4, 3, 2, 1]), which is conceptually related to the target output of the current question. + +**Top 3 snippets** +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Excluding the identical piece, this is the only snippet that touches on reversing a simple numeric list (turning [1, 2, 3, 4, 5] into [5, 4, 3, 2, 1]), which is conceptually related to the target output of the current question. +- `exam-Resit 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Mentions list variable names like 'x', though it doesn't help with slicing logic. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-extra_practice-6-w1-sequences-and-access`: Sequences and Access [w1-sequences-and-access] + Why excluded: This piece contains the exact same question context (numbers = [1..10]), the same target result ([10, 8, 6, 4, 2]), and explicitly discusses the correct and incorrect options. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q13 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `13` +- Topic: Multiple choice +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have a string variable called sentence: +sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.' + +You want to replace only the second occurrence of "book" with "novel" in the sentence and save this as new_sentence. + +So: +print(new_sentence) +should print: +I bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book. + +Which of the following code segments will work as intended? + +Hint: +The string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively. + +**Options** +- `a`: index = sentence.find('book') +index = sentence.find('book', index + 1) +new_sentence = sentence[:index] + 'novel' + sentence[index + 4:] +- `b`: new_sentence = sentence.replace("book", "novel", 2) +new_sentence = new_sentence.replace("novel", "book", 1) +- `c`: Both options will work as intended. +- `d`: None of the given options will work as intended. + +**Correct answer:** `c` + +**Official explanation:** Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of "book" with "novel" and then changes only the first replaced occurrence back to "book", leaving only the second occurrence replaced. + +**Why not certain:** While one snippet shows string slicing, none of the candidates explain the 'string[start:stop]' syntax with two indices, nor do they cover the 'replace()' method's optional 'count' parameter. A student with zero Python knowledge would not be able to determine that 'index + 4' correctly offsets the length of the word 'book' or that the second 'replace' call in Option B effectively reverts only the first occurrence. + +**Gap summary:** The snippets lack foundational explanations for string slicing and common string methods beyond a mention of find() in the question hint. + +**Missing concepts:** String slicing with start and stop indices (sentence[start:stop]); The 'count' parameter in the string.replace() method +**Suggested fix:** Add a concept-based snippet covering 'Common String Methods and Slicing' that demonstrates slicing, find, and replace with multiple occurrences. + +**Best snippet** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: This snippet is the only candidate that explicitly shows string slicing syntax (alphabet[1::2]), which is a fundamental concept required to evaluate Option A in the question. + +**Top 3 snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: This snippet is the only candidate that explicitly shows string slicing syntax (alphabet[1::2]), which is a fundamental concept required to evaluate Option A in the question. +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet describes a string manipulation task (formatting phone numbers and removing separators), which aligns with the general theme of string cleaning and modification found in the question. + +**Minimal sufficient snippets** +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q14 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `14` +- Topic: Multiple choice +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have the following objects loaded in Python: +fruits = ["apple", "banana", "orange"] +count = 3 + +You want to print the following sentence: +I have 3 fruits: apple, banana, and orange. + +Which of the following code fragments will achieve the desired output? + +**Options** +- `a`: message = f"I have {count} fruits: {', '.join(fruits)}." +print(message) +- `b`: message = f"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}." +print(message) +- `c`: Both code fragments will achieve the desired output. +- `d`: Neither of the code fragments will achieve the desired output. + +**Correct answer:** `b` + +**Official explanation:** Option B matches the requested sentence exactly, including the word "and" before the final fruit. Option A joins the list as "apple, banana, orange" and does not produce the exact requested wording. + +**Why not certain:** None of the provided snippets explain f-string syntax (the 'f' prefix and curly braces), list indexing (e.g., fruits[0]), or the behavior of the '.join()' method. Without knowing that '.join()' simply concatenates elements with a separator and doesn't add 'and' before the final item, a student cannot distinguish between Option A and Option B. + +**Gap summary:** The candidate snippets completely lack fundamental information on string formatting and list access techniques required to solve the problem. + +**Missing concepts:** f-strings (literal string interpolation); List indexing (accessing elements by position); String .join() method functionality and limitations +**Suggested fix:** Add a foundational snippet covering string manipulation basics, specifically f-strings and how to join list elements with custom logic vs. the .join() method. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet is the most relevant as it explicitly mentions printing a template string ('[NAME] has received a grade of [GRADE]') using variables, which is the core concept of the question's string formatting requirement. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet is the most relevant as it explicitly mentions printing a template string ('[NAME] has received a grade of [GRADE]') using variables, which is the core concept of the question's string formatting requirement. +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet involves string formatting for phone numbers, which provides some context for how Python handles string construction and manipulation. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q17 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `17` +- Topic: Multiple choice +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Which other code fragment will print the same output as the following? + +from datetime import datetime, timedelta +print((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1) + +**Options** +- `a`: from datetime import datetime, timedelta +print((datetime(2023, 1, 10) - datetime(2023, 1, 1)).days) +- `b`: from datetime import datetime, timedelta +print(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1) +- `c`: from datetime import datetime, timedelta +print((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days) +- `d`: from datetime import datetime, timedelta +print((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days) + +**Correct answer:** `d` + +**Official explanation:** The original expression computes the number of days between January 10 and January 1, then adds 1, which yields 10. Option D also yields 10 by subtracting January 1 from January 11. + +**Why not certain:** Excluding the near-identical past exam piece, there is zero information in the candidate snippets regarding the 'datetime' module, 'strptime' formatting, or datetime subtraction mechanics. The question is unanswerable with general snippets alone. + +**Gap summary:** The candidate set lacks a core conceptual snippet for the Datetime topic (Week 6), which is necessary to understand object constructors and formatting. + +**Missing concepts:** datetime.strptime format codes (e.g., %Y/%m/%d); datetime object constructor: datetime(year, month, day); the result of subtracting datetimes is a timedelta object; timedelta .days attribute +**Suggested fix:** Add a new snippet family for 'Datetime Core' that provides an example of strptime, object creation, and subtraction. + +**Best snippet** +- `kp-8`: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns [w6-comprehensions] + Why: While it doesn't cover the datetime module, it contains key point kp-8 which identifies the 'Which code fragment prints the SAME output as...?' question pattern common in these exams. + +**Top 3 snippets** +- `kp-8`: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns [w6-comprehensions] + Why: While it doesn't cover the datetime module, it contains key point kp-8 which identifies the 'Which code fragment prints the SAME output as...?' question pattern common in these exams. +- `ks-df3b849d59`: Objects and Names [w1-objects-and-names] + Why: Provides meta-knowledge about exam question types, including the 'same output' variety, helping the student recognize the task structure. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why excluded: This past exam piece explicitly explains that subtracting two datetime objects results in a timedelta, that .days provides the difference as an integer, and that adding 1 is part of the logic to calculate the day of the year. This is the exact logic required to evaluate the question. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q18 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `18` +- Topic: Multiple choice +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following DataFrame called df: + Player Age Height +0 John 25 180 +1 Jane 30 165 +2 Alex 27 175 + +You may assume that pandas is already imported as pd. + +Which of the following lines of code will give an error? + +**Options** +- `a`: print(df[['Player', 'Age']]) +- `b`: print(df.loc[df['Height'] > 170, ['Player', 'Age']]) +- `c`: print(df.loc[:, 'Age']) +- `d`: print(df[1, 'Age']) + +**Correct answer:** `d` + +**Official explanation:** Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing in this form does not accept the tuple (1, 'Age') to select a single cell. + +**Why not certain:** The snippets fail to explain the rules for .loc selection, double-bracket column selection, or the fact that standard bracket indexing df[row, col] is invalid. A student cannot determine that option (d) is the error without these specific Pandas indexing rules. + +**Gap summary:** Critical Pandas indexing syntax rules are missing. + +**Missing concepts:** Pandas .loc accessor for label-based indexing; List-based column selection df[['col1', 'col2']]; Syntax limitations of standard bracket indexing (df[] only accepts single keys or slices, not row-column tuples); Boolean indexing in Pandas +**Suggested fix:** Add a 'Pandas Data Selection Guide' snippet that explicitly compares df[...], df.loc[...], and df.iloc[...] and lists common syntax errors. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet is categorized under 'Inspecting and Selecting Data', which is the exact topic of the question. Although the snippet text is truncated, it is the most relevant logical container for the required knowledge. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet is categorized under 'Inspecting and Selecting Data', which is the exact topic of the question. Although the snippet text is truncated, it is the most relevant logical container for the required knowledge. +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Covers basic Pandas structure and implies column selection syntax (df['A']), which provides a starting point for understanding how DataFrames are accessed. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q19 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `19` +- Topic: animals methods +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have the following definition for a class called Animals: + +You need to add two methods to the class: +1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'. +2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'. + +For example, if we execute the following commands: +cat = Animals('kitty', legs=True, sound='Meow!') +fish = Animals('nemo', fin=True, sound='Blob!') +print(cat.walk()) +print(cat.swim()) +print(fish.swim()) +print(fish.walk()) + +the output should be: +Meow! +Cannot swim! +Blob! +Cannot walk! + +Which of the following code segments should you place on the missing lines in the class definition to achieve what you want? + +**Options** +- `a`: def walk(self): + return self.sound if self.legs else 'Cannot walk!' +def swim(self): + return self.sound if self.fin else 'Cannot swim!' +- `b`: def walk(self): + if self.legs = True: + return self.sound + else: + return 'Cannot walk!' +def swim(self): + if self.fin = True: + return self.sound + else: + return 'Cannot swim!' +- `c`: def walk(): + return sound if legs else 'Cannot walk!' +def swim(): + return sound if fin else 'Cannot swim!' +- `d`: def walk(): + if legs == True: + return sound + else: + return 'Cannot walk!' +def swim(): + if fin == True: + return sound + else: + return 'Cannot swim!' + +**Correct answer:** `a` + +**Official explanation:** Option A is the only choice that defines both instance methods with self and correctly returns self.sound when the corresponding boolean attribute is truthy, otherwise the required fallback string. + +**Why not certain:** The current snippets describe the task of writing methods and attributes but do not show the actual Python syntax for instance methods. A student with zero knowledge would not know that they must include 'self' as an argument or use 'self.attribute' to access variables. Options A/B and C/D are distinguished solely by this 'self' syntax, which is never explicitly shown in the provided candidate pieces. + +**Gap summary:** There is a total absence of code examples showing how to define a method within a class and how to reference instance attributes using 'self'. + +**Missing concepts:** Method definition syntax: def method_name(self):; Instance attribute access: self.attribute_name; Ternary operator syntax: value_if_true if condition else value_if_false +**Suggested fix:** Add a new snippet to the OOP Fundamentals topic that provides a clear code example of a class method returning an attribute value. + +**Best snippet** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet directly addresses the concept of adding a 'method' (specifically a 'compare' method) to an existing class to perform logic based on attributes, which is the exact task required by the question. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet directly addresses the concept of adding a 'method' (specifically a 'compare' method) to an existing class to perform logic based on attributes, which is the exact task required by the question. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Explains the definition of classes and attributes (like 'name' and 'mode'), which parallels the 'legs', 'fin', and 'sound' attributes used in the Animals class. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: Provides essential context on return behavior (ensuring a value is returned) and boolean logic (True == 1), which helps in evaluating the truthiness of attributes like 'self.legs'. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `aiq-4`: Comprehensions [w6-comprehensions] +- `exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q21 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `21` +- Topic: datetime weekly dates list +- Status: **insufficient** +- Confidence: `high` + +**Question** + +You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY. + +The function should return a list containing 10 strings representing dates, all in that same format. +The first element of the list should be the original input date. +Each further element of the list should be a string representing the date that is exactly one week after the preceding element of the list. + +Take a look at the following code segment: + +from datetime import datetime, timedelta + +def main(string): + date = datetime.strptime(string, '%d-%m-%Y') + str_list = [date] + for i in range(1, 10): + str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y')) + return str_list + +Will this code segment work as intended? If not, then why not? + +**Options** +- `a`: This code will not work as intended, because there will be 11 strings in the list instead of 10. +- `b`: The code will not work because the two methods strptime() and strftime() are mixed up. +- `c`: This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings. +- `d`: This code segment will work as intended. + +**Correct answer:** `c` + +**Official explanation:** After the first append, the newly added element is a formatted string, so on the next loop iteration the code tries to add a timedelta to a string instead of to a datetime object. + +**Why not certain:** None of the provided snippets mention the 'datetime' or 'timedelta' modules. A student with zero prior Python knowledge would have no way of knowing that strftime() returns a string or that adding a timedelta to a string results in a TypeError without specific documentation on these classes and methods. + +**Gap summary:** The snippet bank is completely missing coverage of the standard 'datetime' library, specifically the return types of its core methods and compatibility with 'timedelta'. + +**Missing concepts:** datetime.strptime return type (datetime object); datetime.strftime return type (string); timedelta addition rules (only works with datetime/date/time objects, not strings) +**Suggested fix:** Add a new snippet family covering common standard library modules like 'datetime', including examples of format conversion and arithmetic. + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This is the only snippet that discusses how Python handles types and values (e.g., bool/int interactions), which is the closest relevant concept to the type-mismatch error in the question, although it does not cover the datetime library specifically. + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This is the only snippet that discusses how Python handles types and values (e.g., bool/int interactions), which is the closest relevant concept to the type-mismatch error in the question, although it does not cover the datetime library specifically. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: While highly insufficient, it provides a general precedent for thinking about return values and type interactions. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q22 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `22` +- Topic: pandas date column from day month year +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following DataFrame called df: + + Day Month Year +0 1 5 2023 +1 8 5 2023 +2 15 5 2023 +3 22 5 2023 +4 29 5 2023 + +You need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this: + + Day Month Year Date +0 1 5 2023 01-05-2023 +1 8 5 2023 08-05-2023 +2 15 5 2023 15-05-2023 +3 22 5 2023 22-05-2023 +4 29 5 2023 29-05-2023 + +Which of the following code segments will achieve what you want? You may assume that the pandas is already imported as pd. + +**Options** +- `a`: from datetime import datetime +df['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])]) +- `b`: from datetime import datetime +df['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])]) +- `c`: from datetime import datetime +df['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])]) +- `d`: from datetime import datetime +df['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])]) + +**Correct answer:** `a` + +**Official explanation:** Option A correctly constructs datetime objects in year-month-day order from the three columns and then formats them into the requested DD-MM-YYYY strings. + +**Why not certain:** While the structural components (new column creation, zip) are partially covered, there is absolutely no information on the 'datetime' module, the specific argument order for the datetime constructor (year, month, day), or the 'strftime' vs 'strptime' methods and their format codes. A student would not be able to distinguish between options A, B, and C. + +**Gap summary:** Major gap in datetime module coverage and string formatting for dates. + +**Missing concepts:** datetime.datetime constructor (year, month, day) order; strftime vs strptime; Format codes like %d, %m, %Y +**Suggested fix:** Add a 'Working with Dates' snippet or detail piece explaining the datetime constructor and basic strftime formatting. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet demonstrates creating a new Series from existing data via a transformation (.map/split), which matches the high-level pattern of transforming columns to create a new one. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet demonstrates creating a new Series from existing data via a transformation (.map/split), which matches the high-level pattern of transforming columns to create a new one. +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows how to use zip() to iterate over multiple sequences simultaneously, which is the mechanism used in the correct answer's list comprehension. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q01 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `1` +- Topic: 1_Basics_Logic_1 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Suppose you have a list called x containing tuples, where +x = [(1, 2), (3, 4), (5, 6), (7, 8)] + +Which of the following lines of code will print True? + +**Options** +- `a`: print(x[0][1] * x[-3][0] == x[2][1]) +- `b`: print(x[1][0] + x[-2][0] == x[-1][1]) +- `c`: print(x[-1][0] - x[-2][0] == x[0][1]) +- `d`: All lines of code will print True. + +**Correct answer:** `d` + +**Official explanation:** The three code lines evaluate to 2 * 3 == 6, 3 + 5 == 8, and 7 - 5 == 2, so each one is True. Therefore the correct choice is that all lines print True. + +**Why not certain:** While the identical question exists in the library, there is no general-purpose snippet that explains the rules of 0-based indexing, negative indexing (x[-1]), or double-indexing into nested tuples (x[i][j]). Without the identical question, a student with zero knowledge could not derive the answer. + +**Gap summary:** Major gap in foundational syntax for accessing elements in sequences and nested structures. + +**Missing concepts:** 0-based indexing; Negative indexing (counting from the end of a list); Accessing elements within nested structures (list of tuples) +**Suggested fix:** Add a 'General Concept' or 'Cheat Sheet' snippet for Python Indexing that explicitly demonstrates positive vs. negative indices and how to index into a list of tuples. + +**Best snippet** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This is the only non-identical snippet that mentions indices/order (sorting) and 'stepping backwards', which is the closest conceptual link to negative indexing, though it is still insufficient. + +**Top 3 snippets** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This is the only non-identical snippet that mentions indices/order (sorting) and 'stepping backwards', which is the closest conceptual link to negative indexing, though it is still insufficient. +- `exam-Trial final exam Introduction to Python-3-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why: Helps conceptualize a list containing other structures (dictionaries instead of tuples), which is useful for understanding nested access. + +**Minimal sufficient snippets** +- `exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why excluded: Contains the exact question, the list definition, and a step-by-step breakdown of the arithmetic logic. +- `exam-Resit 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why excluded: Contains the same question structure and the identical evaluation logic (e.g., 2 * 3 == 6). + +### resit-solutions-for-introduction-to-python-35761538-q10 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `10` +- Topic: String Methods +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What is the output of the following code segment? + +x = 'Hello, World!' +print([char for char in x if char.islower()]) + +**Options** +- `a`: ['e', 'l', 'l', 'o', 'o', 'r', 'l', 'd'] +- `b`: ['e', 'l', 'l', 'o', ',', ' ', 'w', 'o', 'r', 'l', 'd', '!'] +- `c`: ['h', 'e', 'l', 'l', 'o', 'w', 'o', 'r', 'l', 'd'] +- `d`: ['H', 'e', 'l', 'l', 'o', 'W', 'o', 'r', 'l', 'd'] + +**Correct answer:** `a` + +**Official explanation:** The comprehension keeps only the lowercase letters in the string. Punctuation, spaces, and uppercase letters are skipped by islower(). + +**Why not certain:** The snippets fail to explain the syntax of list comprehensions ([item for item in iterable if condition]) or the functionality of the .islower() method. A student without prior knowledge would not know what 'islower' filters for (letters vs punctuation/spaces) or how the loop-within-brackets structure works. + +**Gap summary:** The primary gaps are the list comprehension syntax and the definition of boolean string methods like .islower(). + +**Missing concepts:** List Comprehensions; .islower() string method; Filtering logic in comprehensions +**Suggested fix:** Add a snippet specifically explaining list comprehensions with filtering, and another covering common string validation methods (.islower, .isupper, .isdigit, .isalpha). + +**Best snippet** +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] + Why: This family contains conceptual references to string methods (capitalize) and higher-order patterns (applying transformations to iterables), which are the closest conceptual matches to list comprehensions and method calls, even though the specific syntax is missing. + +**Top 3 snippets** +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] + Why: This family contains conceptual references to string methods (capitalize) and higher-order patterns (applying transformations to iterables), which are the closest conceptual matches to list comprehensions and method calls, even though the specific syntax is missing. +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Shows a string being converted to a list (list(alphabet...)), which helps the student understand that the output of the question's code might be a list of characters. +- `exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: Identifies 'abc' as a string (str), which confirms the data type of the input variable 'x'. + +**Minimal sufficient snippets** +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q11 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `11` +- Topic: Functions and Imports +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What will be the output of the following code segment? + +list1 = [5, 10, 15, 20] +list2 = [2, 4, 6, 8] +result = [] + +for a, b in zip(list1, list2): + result.append(a // b) + +print(result) + +**Options** +- `a`: [1, 2, 3, 4] +- `b`: [2, 2, 2, 2] +- `c`: [6, 12, 18, 24] +- `d`: [2.5, 2.5, 2.5, 2.5] + +**Correct answer:** `b` + +**Official explanation:** The code uses floor division (`//`) on each pair from zip, so the results are 2, 2, 2, and 2. + +**Why not certain:** None of the provided snippets explain the `zip()` function or the floor division operator (`//`). A student with zero knowledge would not know how to combine the lists or what calculation is being performed. + +**Gap summary:** Critical missing explanations for the zip() built-in and the floor division operator. + +**Missing concepts:** zip() function mechanics; floor division operator (//); iteration over zipped pairs +**Suggested fix:** Add a key point or AI example explaining how zip(a, b) pairs elements and how // returns the integer quotient (rounding down). + +**Best snippet** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This snippet is the only one showing `list.append()`, which is used in the question to build the results list. + +**Top 3 snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This snippet is the only one showing `list.append()`, which is used in the question to build the results list. +- `ks-b6a39f66a2`: Functions and Imports [w1-functions-and-imports] + Why: Explains that `print` is a built-in function used to output arguments to the screen. + +**Minimal sufficient snippets** +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] +- `ks-b6a39f66a2`: Functions and Imports [w1-functions-and-imports] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q12 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `12` +- Topic: Sequences and Access +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have a list called numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]. +Which of the following lines of code will not create a list with the name subset and the value [10, 8, 6, 4, 2]? + +**Options** +- `a`: subset = numbers[::-2][::-1] +- `b`: subset = numbers[-1::-2] +- `c`: subset = numbers[::-1][::2] +- `d`: subset = numbers[::-2] + +**Correct answer:** `a` + +**Official explanation:** A reverses the reversed-even slice, producing [2, 4, 6, 8, 10] instead of the requested list. The other three options all evaluate to [10, 8, 6, 4, 2]. + +**Why not certain:** If the near-identical past exam piece is excluded, there are no snippets in the current candidate set that explain the fundamentals of Python slicing syntax ([start:stop:step]). A student without prior knowledge would not be able to deduce the behavior of negative steps or chained slices from the remaining snippets. + +**Gap summary:** The repository is missing foundational material on sequence slicing, which is a core concept for the 'Sequences and Access' topic. + +**Missing concepts:** Slicing syntax [start:stop:step]; Negative step behavior in slices (reversing); Chained slicing behavior +**Suggested fix:** Add a concept-based snippet (not an exam question) that explicitly explains how [::1], [::-1], [::2], and [start::step] work with examples using a simple list. + +**Best snippet** +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Aside from the identical exam piece, this is the only other snippet that deals with transforming and reversing lists (using sorting), although it lacks the specific slicing syntax ([start:stop:step]) required for this question. + +**Top 3 snippets** +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Aside from the identical exam piece, this is the only other snippet that deals with transforming and reversing lists (using sorting), although it lacks the specific slicing syntax ([start:stop:step]) required for this question. + +**Minimal sufficient snippets** +- `exam-extra_practice-6-w1-sequences-and-access`: Sequences and Access [w1-sequences-and-access] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-extra_practice-6-w1-sequences-and-access`: Sequences and Access [w1-sequences-and-access] + Why excluded: This is the exact same question, including the same list values and the specific list being created, although the mapping of letters (a, b, c, d) to the specific code lines in the explanation may differ slightly. + +### resit-solutions-for-introduction-to-python-35761538-q13 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `13` +- Topic: string - find - 3 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have a string variable called sentence: +sentence = 'I bought a book about programming. The book has a lot of exercises. I enjoy reading a good book.' + +You want to replace only the second occurrence of "book" with "novel" in the sentence and save this as new_sentence. + +So: +print(new_sentence) +should print: +I bought a book about programming. The novel has a lot of exercises. I enjoy reading a good book. + +Which of the following code segments will work as intended? + +Hint: +The string find() method takes three arguments: value, start and end. The first argument is required and is the value to search for. The second and third argument are optional, they are indices specifying where to start and end the search, respectively. + +**Options** +- `a`: index = sentence.find('book') +index = sentence.find('book', index + 1) +new_sentence = sentence[:index] + 'novel' + sentence[index + 4:] +- `b`: new_sentence = sentence.replace("book", "novel", 2) +new_sentence = new_sentence.replace("novel", "book", 1) +- `c`: Both options will work as intended. +- `d`: None of the options will work as intended. + +**Correct answer:** `c` + +**Official explanation:** Option A finds the second occurrence and replaces it by slicing. Option B first replaces the first two occurrences of "book" with "novel" and then changes only the first replaced occurrence back to "book", so only the second occurrence remains replaced. + +**Why not certain:** The candidate snippets do not explain the `replace()` method's third argument (count), which is central to Option B. While the question provides a hint for `find()`, none of the snippets demonstrate the string concatenation pattern `s[:i] + 'new' + s[i+len:]` used in Option A. + +**Gap summary:** Missing core documentation for string methods 'replace' and practical string reconstruction using slicing. + +**Missing concepts:** string.replace(old, new, count) behavior; String reconstruction via slicing and concatenation; Practical usage of find() with the start index parameter +**Suggested fix:** Add a snippet covering common string methods (find, replace, count) and an example of 'surgical' string editing using slicing. + +**Best snippet** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet involves extracting specific substrings (TLDs) from a string (URL), which conceptually aligns with the string manipulation and positioning logic required for this question. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet involves extracting specific substrings (TLDs) from a string (URL), which conceptually aligns with the string manipulation and positioning logic required for this question. +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Shows string slicing syntax (e.g., alphabet[1::2]), which is necessary to understand Option A's use of indices to reconstruct the sentence. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q14 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `14` +- Topic: string - fstring - 3 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have the following objects loaded in Python: +fruits = ["apple", "banana", "orange"] +count = 3 + +You want to print the following sentence: +I have 3 fruits: apple, banana, and orange. + +Which of the following code fragments will achieve the desired output? + +**Options** +- `a`: message = f"I have {count} fruits: {', '.join(fruits)}." +print(message) +- `b`: message = f"I have {count} fruits: {fruits[0]}, {fruits[1]}, and {fruits[2]}." +print(message) +- `c`: Both code fragments will achieve the desired output. +- `d`: Neither of the code fragments will achieve the desired output. + +**Correct answer:** `b` + +**Official explanation:** Option B matches the required sentence exactly, including the word "and" before the final fruit. Option A joins the list without "and", so it does not produce the exact requested output. + +**Why not certain:** None of the provided snippets explain f-string syntax (f"..."), list indexing (how to access 'apple' via fruits[0]), or the .join() method. A student without prior knowledge would not understand the syntax used in the options. + +**Gap summary:** The candidate snippets focus on high-level exam questions rather than the foundational syntax required (f-strings and indexing). + +**Missing concepts:** f-string syntax and variable interpolation; List indexing (0-based access); String .join() method functionality +**Suggested fix:** Add a foundational snippet explaining how f-strings work and how to access specific elements in a list using square brackets. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet involves formatting a string using list/dictionary data to produce a specific sentence pattern, which is the exact task in the question. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet involves formatting a string using list/dictionary data to produce a specific sentence pattern, which is the exact task in the question. +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Discusses writing a function to format strings (phone numbers), which relates to the concept of string manipulation and output structure. +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Mentions list manipulation, though it focuses more on slicing than simple indexing. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q18 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `18` +- Topic: pandas - easy - 3 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following DataFrame called df: + Player Age Height +0 John 25 180 +1 Jane 30 165 +2 Alex 27 175 + +You may assume that pandas is already imported as pd. + +Which of the following lines of code will give an error? + +**Options** +- `a`: print(df.loc[:, 'Age']) +- `b`: print(df.loc[df['Height'] > 170, ['Player', 'Age']]) +- `c`: print(df[['Player', 'Age']]) +- `d`: print(df[1, 'Age']) + +**Correct answer:** `d` + +**Official explanation:** Options A, B, and C are valid pandas selections. Option D is invalid because standard bracket indexing does not accept the tuple (1, 'Age') in this form. + +**Why not certain:** The snippets do not explicitly show the difference between .loc indexing and standard bracket indexing. A student wouldn't know that df[row, col] is invalid while df.loc[row, col] is valid based on these snippets. + +**Gap summary:** There is no information explaining the specific syntax rules for Pandas DataFrame indexing, specifically why tuples are not allowed in standard brackets. + +**Missing concepts:** Pandas .loc vs [] indexing syntax; Multi-axis indexing rules in DataFrames +**Suggested fix:** Add a snippet or exam question that explicitly demonstrates that df[1, 'col'] raises a KeyError or TypeError, whereas df.loc[1, 'col'] works. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet is the most relevant as it explicitly covers 'Inspecting and Selecting Data' in Pandas, though the provided text is minimal. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet is the most relevant as it explicitly covers 'Inspecting and Selecting Data' in Pandas, though the provided text is minimal. +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Provides context for standard column selection in Pandas (df['A']), which helps rule out simple bracket indexing for multiple axes. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q21 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `21` +- Topic: 8_Datetime_Function_1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You need to write a function called main, which accepts a string as an argument. The string represents a date as DD-MM-YYYY. + +The function should return a list containing 10 strings representing dates, all in that same format. +The first element of the list should be the original input date. +Each further element of the list should be a string representing the date that is exactly one week after the preceding element of the list. + +Take a look at the following code segment: + +from datetime import datetime, timedelta + +def main(string): + date = datetime.strptime(string, '%d-%m-%Y') + str_list = [date] + for i in range(1, 10): + str_list.append((str_list[i-1] + timedelta(weeks=1)).strftime('%d-%m-%Y')) + return str_list + +Will this code segment work as intended? If not, then why not? + +**Options** +- `a`: The code will not work because the two methods strptime() and strftime() are mixed up. +- `b`: This code will not work because str_list[i-1] is a string. Timedelta objects can only be added to datetime objects, and cannot be added to strings. +- `c`: This code will not work as intended, because there will be 11 strings in the list instead of 10. +- `d`: This code segment will work as intended. + +**Correct answer:** `b` + +**Official explanation:** After the first append inside the loop, the list contains formatted date strings. On the next iteration the code tries to add a timedelta to that string, which is not allowed. + +**Why not certain:** None of the provided snippets explain the 'datetime' module, the difference between 'strptime' and 'strftime', or the fact that 'timedelta' objects cannot be added to strings. Without this domain knowledge, a student with zero Python experience cannot distinguish between options (a) and (b). + +**Gap summary:** Missing core documentation for the datetime library and type-safety rules for datetime arithmetic. + +**Missing concepts:** datetime.strptime vs datetime.strftime; timedelta arithmetic (cannot add to strings); datetime object vs formatted string +**Suggested fix:** Add a dedicated 'Datetime' snippet family covering strptime, strftime, and timedelta usage. + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: It contains general debugging advice to trace returned values and observe list state after each call, which is the key to spotting that the list elements change from datetime objects to strings. + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: It contains general debugging advice to trace returned values and observe list state after each call, which is the key to spotting that the list elements change from datetime objects to strings. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q22 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `22` +- Topic: 8_Datetime_Hard_3 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose you have the following DataFrame called df: + + Day Month Year +0 1 5 2023 +1 8 5 2023 +2 15 5 2023 +3 22 5 2023 +4 29 5 2023 + +You need to create a new column called Date that contains strings representing the dates as constructed from the Day, Month and Year columns. That is, finally the DataFrame should look like this: + + Day Month Year Date +0 1 5 2023 01-05-2023 +1 8 5 2023 08-05-2023 +2 15 5 2023 15-05-2023 +3 22 5 2023 22-05-2023 +4 29 5 2023 29-05-2023 + +Which of the following code segments will achieve what you want? You may assume that the pandas module is already imported as pd. + +**Options** +- `a`: from datetime import datetime +df['Date'] = pd.Series([datetime(y, m, d).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])]) +- `b`: from datetime import datetime +df['Date'] = pd.Series([datetime.strptime(d, m, y, '%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])]) +- `c`: from datetime import datetime +df['Date'] = pd.Series([datetime(d, m, y).strftime('%d-%m-%Y') for d, m, y in zip(df['Day'], df['Month'], df['Year'])]) +- `d`: from datetime import datetime +df['Date'] = pd.Series([datetime.strptime(date, '%d-%m-%Y') for date in zip(df['Day'], df['Month'], df['Year'])]) + +**Correct answer:** `a` + +**Official explanation:** Option A builds real datetime objects using year, month, and day in the correct order and then formats each one as DD-MM-YYYY. + +**Why not certain:** None of the candidate snippets provide information about the 'datetime' module, which is essential for solving this problem. There is no guidance on the 'datetime(year, month, day)' constructor's argument order, the difference between 'strftime' (formatting) and 'strptime' (parsing), or the specific formatting codes (like %d, %m, %Y) required. A student with zero knowledge would be forced to guess between option A and C based on the variable order alone. + +**Gap summary:** The snippets provide the structural framework for Pandas column creation but completely omit the 'datetime' module logic required to construct the date string. + +**Missing concepts:** datetime.datetime(year, month, day) constructor argument order; Usage of .strftime() to format datetime objects into strings; Difference between strftime and strptime; Date formatting syntax (%d, %m, %Y) +**Suggested fix:** Add a new snippet covering the basics of the 'datetime' module, specifically showing object construction and the use of strftime for formatting. + +**Best snippet** +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet involves processing parallel lists (names and ages), which is the standard context in this course for introducing the 'zip' function. This helps a student understand the iteration structure used in the correct answer. + +**Top 3 snippets** +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet involves processing parallel lists (names and ages), which is the standard context in this course for introducing the 'zip' function. This helps a student understand the iteration structure used in the correct answer. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Demonstrates the structural pattern of creating a new DataFrame column ('C') based on values from existing columns ('A' and 'B'). + +**Minimal sufficient snippets** +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q24 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `24` +- Topic: pandas - lambda - 3 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +What will be the output of the following lines of code? + +import pandas as pd + +df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}) +df['C'] = df['A'].map(lambda x: x + df['B'].sum()) + +print(df) + +**Options** +- `a`: A B C +0 1 4 16 +1 2 5 17 +2 3 6 18 +- `b`: A B C +0 1 4 18 +1 2 5 21 +2 3 6 24 +- `c`: A B C +0 1 4 12 +1 2 5 15 +2 3 6 18 +- `d`: A B C +0 1 4 9 +1 2 5 12 +2 3 6 15 + +**Correct answer:** `a` + +**Official explanation:** df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing 16, 17, and 18 in column C. + +**Why not certain:** While the snippets cover DataFrame creation and the existence of .map(), there is no information explaining the 'lambda' syntax or the Series '.sum()' method. A zero-knowledge student would not understand that 'x' in the lambda refers to the values in column 'A' or that '.sum()' results in a single scalar value added to each element. + +**Gap summary:** The snippets fail to explain anonymous functions (lambdas) and aggregation methods like .sum(). + +**Missing concepts:** lambda functions syntax (lambda x: ...); Series.sum() aggregation method; scoping of variables inside a lambda when used with .map() +**Suggested fix:** Add a snippet or example piece that explains lambda functions in the context of Pandas operations, and a piece demonstrating Series aggregation methods. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet explicitly mentions the .map() method and explains that it allows applying a function to a Series, which is the central operation in the question. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet explicitly mentions the .map() method and explains that it allows applying a function to a Series, which is the central operation in the question. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows the pattern of creating a new column ('C') in an existing DataFrame, helping the student understand the assignment part of the code. +- `cs-b46633d18d`: Combining Data [w5-combining-data] + Why: Provides the syntax for DataFrame initialization using a dictionary, which allows the student to parse the first few lines of the code context. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] +- `cs-b46633d18d`: Combining Data [w5-combining-data] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### sample-final-plus-answers-q01 + +- Exam: `sample-final-plus-answers` +- Question number: `1` +- Topic: vehicle class defaults +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. +The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string "land". +For example, if we create a Vehicle object as: +my_car = Vehicle("Mazda") +then the following two conditions should both be true: +my_car.name == "Mazda" +my_car.mode == "land" +Which of the following code segments achieves what you want? + +**Options** +- `a`: class Vehicle: + def __init__(self, vehicle_name, vehicle_mode="land"): + self.name = vehicle_name + self.mode = vehicle_mode +- `b`: class Vehicle: + def __init__(self, vehicle_name, vehicle_mode): + self.name = vehicle_name + self.mode = vehicle_mode +- `c`: class Vehicle: + def __init__(self, vehicle_name, vehicle_mode="land"): + return name, mode +- `d`: class Vehicle: + def __init__(vehicle_name, vehicle_mode): + name = vehicle_name + mode = vehicle_mode + +**Correct answer:** `a` + +**Official explanation:** Option A correctly defines the constructor with `self`, stores both attributes on the instance, and gives `vehicle_mode` the default value `"land"`. + +**Why not certain:** The available non-identical snippets do not explain 'class' syntax, the '__init__' constructor, or the requirement of the 'self' parameter. A student with zero knowledge would not be able to distinguish between the options based on the provided logic alone. + +**Gap summary:** There is a total lack of OOP syntax documentation (classes, constructors, self) outside of the near-identical exam questions. + +**Missing concepts:** class definition syntax; __init__ method purpose and syntax; self parameter in instance methods; instance attribute assignment (self.name = ...) +**Suggested fix:** Add a foundational OOP snippet that shows a simple class definition with a constructor, usage of self, and default arguments. + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: While it doesn't cover classes, it is the only family that mentions 'Arguments' and shows the syntax for default values (e.g., factor=2) which is a core part of the question. + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: While it doesn't cover classes, it is the only family that mentions 'Arguments' and shows the syntax for default values (e.g., factor=2) which is a core part of the question. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: Provides a hint towards default argument syntax, although insufficient for the full class structure. + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why excluded: This piece contains the exact text of the question regarding the Vehicle class and its attributes. +- `exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures`: OOP Fundamentals [w4-oop-fundamentals] + Why excluded: This piece is a near-identical duplicate of the question, providing the same scenario about the Vehicle class. + +### sample-final-plus-answers-q08 + +- Exam: `sample-final-plus-answers` +- Question number: `8` +- Topic: dictionary comprehension lengths +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have a list of strings called list_1, in which every element is unique. +Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key? + +**Options** +- `a`: {item: len(item) for item in list_1} +- `b`: [len(item) for item in list_1] +- `c`: {item for item in list_1 if len(item) > 0} +- `d`: {len(item): item for item in list_1} + +**Correct answer:** `a` + +**Official explanation:** Option A is the only dictionary comprehension that maps each string to its own length. Option B makes a list, Option C makes a set, and Option D reverses the intended key-value direction. + +**Why not certain:** After excluding the identical exam pieces, none of the remaining snippets explain the 'for item in list' comprehension syntax within curly braces. A student with zero Python knowledge wouldn't know how to construct the dictionary dynamically or what the 'len()' function does. + +**Gap summary:** The collection lacks a general conceptual explanation of Python comprehensions and basic built-in functions like 'len()'. + +**Missing concepts:** dictionary comprehension syntax; the len() function for string length; distinction between set and dictionary comprehension syntax +**Suggested fix:** Add a dedicated 'Python Basics: Comprehensions' snippet that shows the syntax `{k: v for x in y}` for dictionaries and explains the `len()` function. + +**Best snippet** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows the standard dictionary format `{key: value}`, which helps a novice identify that a dictionary requires both a key and a value separated by a colon, helping eliminate Option B and C. + +**Top 3 snippets** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows the standard dictionary format `{key: value}`, which helps a novice identify that a dictionary requires both a key and a value separated by a colon, helping eliminate Option B and C. +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: The explanation mentions that `{...}` can result in a set (Option C), helping the student understand that curly braces are used for both sets and dictionaries. +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Provides another example of mapping keys to values in a dictionary context, reinforcing the conceptual mapping required by the question. + +**Minimal sufficient snippets** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why excluded: This is an exact duplicate of the provided question, including the same list name ('list_1'), logic, and options. +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why excluded: Nearly identical question that maps a list of strings ('words') to their lengths in a dictionary, demonstrating the exact code pattern required. + +### sample-final-plus-answers-q19 + +- Exam: `sample-final-plus-answers` +- Question number: `19` +- Topic: Dictionary running totals +- Status: **insufficient** +- Confidence: `high` + +**Question** + +You have to write a function called main that accepts a dictionary as an input argument. +Both the keys and the values of the input are integers. +Return another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary whose keys are smaller than or equal to the output key in question. +For example: +main({5: 1, 2: 5, 4: 2}) +should return a dictionary that is equal to: +{5: 8, 2: 5, 4: 7} +Which of the following programs works as intended? + +**Options** +- `a`: def main(d): + result = {} + for output_key in d.keys(): + result[output_key] = sum([v for k, v in d.items() if k <= output_key]) + return result +- `b`: def main(d1): + running_total = 0 + d2 = {} + for key in sorted(d1.keys()): + running_total += d1[key] + d2[key] = running_total + return d2 +- `c`: Both of the above work as intended +- `d`: None of the above works as intended + +**Correct answer:** `c` + +**Official explanation:** The first program computes each output value by summing all input values whose keys are less than or equal to the current key. The second program accumulates values in ascending key order, which yields the same running totals for each key. + +**Why not certain:** While basic dictionary creation is covered, the snippets completely lack coverage of 'sorted()', dictionary '.items()' iteration, and the specific syntax of list comprehensions with conditional filtering ('[v for k, v in d.items() if k <= ...]'). A student with zero knowledge would not be able to deduce that 'sorted(d1.keys())' or the list comprehension work as intended. + +**Gap summary:** The current snippets do not cover the advanced dictionary iteration and sorting techniques used in the exam question. + +**Missing concepts:** sorted() function for dictionary keys; dictionary .items() method; list comprehensions with conditional filtering (if clause); running total/accumulation logic across iterations +**Suggested fix:** Add a snippet family that demonstrates iterating over sorted dictionary keys and another showing a list comprehension that filters dictionary items. + +**Best snippet** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet shows the fundamental pattern of building a new dictionary by iterating over a collection and assigning values to keys (e.g., word_lengths[word] = ...), which is central to both programs provided in the question. + +**Top 3 snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet shows the fundamental pattern of building a new dictionary by iterating over a collection and assigning values to keys (e.g., word_lengths[word] = ...), which is central to both programs provided in the question. +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Demonstrates the concept of summing values within a function, which helps understand the goal of calculating a total (sum of values). +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows basic dictionary usage for retrieving values, which is necessary for understanding the lookup logic in both programs. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Dictionary creation pattern. +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Summation concept. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### sample-final-plus-answers-q24 + +- Exam: `sample-final-plus-answers` +- Question number: `24` +- Topic: Circle area imports and aliases +- Status: **insufficient** +- Confidence: `low` + +**Question** + +If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula: +πr² +Suppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area? + +**Options** +- `a`: import math +print(math.pi * r ** 2) +- `b`: from math import pi +print(pi * r ** 2) +- `c`: import math as constants +print(math.pi * r ** 2) +- `d`: from math import pi as constant +print(constant * r ** 2) + +**Correct answer:** `c` + +**Official explanation:** Option C aliases the module as `constants`, so `math.pi` is not defined there. The other three options reference pi correctly. + +**Why not certain:** Excluding the near-identical past exam piece, there are no snippets explaining how 'import', 'from ... import', or 'as' aliases affect the available namespace in Python. + +**Gap summary:** The candidate snippets lack any general explanation of Python's import system and aliasing mechanics. + +**Missing concepts:** Module aliasing (import X as Y); Namespace availability after aliasing; From ... import syntax +**Suggested fix:** Add a foundational snippet or lecture summary covering the different ways to import modules and their effects on the local namespace. + +**Best snippet** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why: While it doesn't cover imports, it demonstrates the exponentiation operator (**2) used in the area formula (pi * r ** 2). + +**Top 3 snippets** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why: While it doesn't cover imports, it demonstrates the exponentiation operator (**2) used in the area formula (pi * r ** 2). + +**Minimal sufficient snippets** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-24-w2-conditions`: Functions and Imports [w1-functions-and-imports] + Why excluded: This piece contains the exact same question and explicitly explains that aliasing a module (e.g., 'import math as constants') makes the original name ('math') unavailable. + +### trial-final-exam-solutions-introduction-to-python-3077951-q01 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `1` +- Topic: 6-OOP-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You'd like to define a class called Vehicle. It should have two attributes: "name" and "mode", which you want to be initialized at the time of object construction. + +The "name" attribute can be any string, and it must be passed to the object constructor. The "mode" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor, then the "mode" attribute should be equal to "land". + +For example, if we create a Vehicle object as: +my_car = Vehicle("Mazda") +then the following two conditions should both be true: +my_car.name == "Mazda" +my_car.mode == "land" + +Which of the following code segments achieves what you want? + +**Options** +- `a`: class Vehicle: + def __init__(self, vehicle_name, vehicle_mode="land"): + self.name = vehicle_name + self.mode = vehicle_mode +- `b`: class Vehicle: + def __init__(self, vehicle_name, vehicle_mode): + self.name = vehicle_name + self.mode = vehicle_mode +- `c`: class Vehicle: + def __init__(self, vehicle_name, vehicle_mode="land"): + return name, mode +- `d`: class Vehicle: + def __init__(vehicle_name, vehicle_mode): + name = vehicle_name + mode = vehicle_mode + +**Correct answer:** `a` + +**Official explanation:** Option A defines an initializer with a required vehicle name and a default mode of "land", then stores both on the instance using self. + +**Why not certain:** While the student can 'cheat' using identical past exam questions, the general snippets do not explain how to define a class, the purpose of __init__, or why 'self' is required in the argument list and for attribute assignment. A zero-knowledge student would not understand why Option A is correct over Option D (missing self) or Option C (using return). + +**Gap summary:** The snippets lack a foundational explanation of Python class syntax, specifically the constructor method and instance attribute assignment. + +**Missing concepts:** Class definition (class Name:); The __init__ method (constructor); The self parameter in methods; Instance attribute assignment (self.attribute = value) +**Suggested fix:** Add a conceptual snippet explaining the structure of a Python class and its __init__ method. + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This family contains a piece on 'Mutable default argument' (def f(lst=[])) which demonstrates the syntax for default values in Python, directly helping with the 'mode="land"' part of the question. + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: This family contains a piece on 'Mutable default argument' (def f(lst=[])) which demonstrates the syntax for default values in Python, directly helping with the 'mode="land"' part of the question. +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides context for OOP and methods, though it lacks the critical syntax for class initialization. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why excluded: This piece contains the exact text of the current question, including the Vehicle class requirements. +- `exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures`: OOP Fundamentals [w4-oop-fundamentals] + Why excluded: This is another identical version of the same question from a different exam source. + +### trial-final-exam-solutions-introduction-to-python-3077951-q05 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `5` +- Topic: 7-pandas-new_column-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have a pandas DataFrame called df. It has a column called "A" and a column called "B". Both contain numbers. + +You'd like to create a column called "C", which contains the sum of the numbers in columns "A" and "B". Which of the following code lines will achieve what you want? + +**Options** +- `a`: df["C"] = df["A"] + df["B"] +- `b`: df["C"] = df["A"].map(lambda x: x + df["B"]) +- `c`: df["C"] = df.columns["A" + "B"] +- `d`: df["C"] = df["A" + "B"] + +**Correct answer:** `a` + +**Official explanation:** Option A performs elementwise addition between columns A and B and stores the result in column C. The other options either misuse map, index into the columns object incorrectly, or look for a non-existent combined column name. + +**Why not certain:** While the near-identical pieces provide the answer directly, the remaining snippets do not explicitly show the syntax for creating a new column by adding two existing columns (df['C'] = df['A'] + df['B']). A student with zero prior knowledge would not be able to deduce the specific assignment syntax from the provided context. + +**Gap summary:** The candidate list lacks a general-purpose reference or lecture snippet explaining Pandas arithmetic and column creation. + +**Missing concepts:** Pandas vectorized column addition syntax; Creating/Assigning a new column in a DataFrame +**Suggested fix:** Add a snippet from Week 5 lecture materials that explicitly covers 'Vectorized Operations' and 'Adding New Columns'. + +**Best snippet** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: This is the most relevant non-identical snippet as it discusses performing mathematical operations (square of difference) on a Pandas Series, illustrating the concept of element-wise/vectorized operations. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: This is the most relevant non-identical snippet as it discusses performing mathematical operations (square of difference) on a Pandas Series, illustrating the concept of element-wise/vectorized operations. +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Provides a visual example of a printed Pandas DataFrame with columns A, B, C, and D, which helps the student visualize the data structure being discussed. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why excluded: This piece contains the exact same question text, topic, and scenario as the target question. +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why excluded: This is a near-identical version of the question from a different year, including partial explanation text about vectorized addition. + +### trial-final-exam-solutions-introduction-to-python-3077951-q06 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `6` +- Topic: 7-pandas-selection-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have a pandas DataFrame called df that looks like this, when printed: + + A B C D +1 9.1 9.5 9.0 6.0 +2 6.4 8.2 7.5 1.7 +3 2.5 5.3 8.8 3.0 +4 6.7 3.6 7.2 6.9 +5 8.4 1.9 8.2 3.3 +6 8.1 8.4 9.9 2.2 + +Suppose that you'd like to create a new DataFrame that only contains those elements of column "B" in df that have an even-numbered index. Which of the following code lines will achieve what you want? + +**Options** +- `a`: df.loc[df.index % 2 == 0, ["B"]] +- `b`: df[2, 4, 6, "B"] +- `c`: df.iloc[[2, 4, 6], 2] +- `d`: df.loc[2::2, "B"] + +**Correct answer:** `a` + +**Official explanation:** Option A filters rows whose index is even and selects column B while keeping the result as a DataFrame by using [["B"]]. Option D would return a Series, not a DataFrame, and the other options do not select the requested data correctly. + +**Why not certain:** Excluding the near-identical exam items, there are no snippets explaining .loc, .iloc, boolean indexing on indices, or the distinction between returning a Series vs. a DataFrame (the list-in-brackets syntax). + +**Gap summary:** The current selection lacks any general documentation or lecture-based explanation of pandas selection methods (.loc vs .iloc) and the syntactical difference between single-label and list-of-labels selection. + +**Missing concepts:** pandas .loc for label-based selection; Boolean indexing on DataFrame indices; Series vs DataFrame return types in column selection (['Col'] vs [['Col']]); The modulo operator (%) used for even/odd filtering +**Suggested fix:** Add a general lecture-based snippet from Week 5 covering .loc, boolean indexing, and selection result types. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: While it focuses on column creation/addition, it is the only remaining snippet that demonstrates basic pandas DataFrame column indexing syntax (df['A']). + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: While it focuses on column creation/addition, it is the only remaining snippet that demonstrates basic pandas DataFrame column indexing syntax (df['A']). +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Reinforces basic pandas column operations and vectorized addition logic. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why excluded: This piece contains the exact DataFrame and the first part of the question text. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why excluded: This piece describes the logic of selecting column 'B' for even indices and explains why using a list ['B'] returns a DataFrame. + +### trial-final-exam-solutions-introduction-to-python-3077951-q08 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `8` +- Topic: 7-pandas-string-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +There is a pandas Series called s, which contains Dutch municipality and corresponding province names, separated by a semicolon and a whitespace. The following, for example, is an element of this Series: "Amsterdam; Noord-Holland". + +You'd like to create a new Series that only contains the municipality names from s in the same order. Which of the following code lines will achieve what you want? + +**Options** +- `a`: s.map(lambda x: x.split("; ")[0]) +- `b`: s.split("; ")[0] +- `c`: s.lambda(x.split("; ")) +- `d`: s.str[:9] + +**Correct answer:** `a` + +**Official explanation:** Option A applies split('; ') to each element in the Series and takes the first part, which is the municipality name. The other options either do not operate elementwise or do not reliably extract the municipality name. + +**Why not certain:** Excluding the identical past exam piece, none of the remaining snippets explain the '.map(lambda...)' syntax or the '.str' accessor required to perform element-wise string operations on a pandas Series. A student would not know how to bridge standard string splitting with pandas Series operations. + +**Gap summary:** There is a complete lack of general documentation or snippets explaining how to manipulate strings within a pandas Series. + +**Missing concepts:** pandas Series .map() method; lambda functions in pandas context; pandas Series .str accessors; element-wise string splitting in pandas +**Suggested fix:** Add a general 'Pandas String Operations' snippet that explains the '.str' accessor (e.g., s.str.split().str[0]) and the '.map(lambda x: ...)' pattern for custom transformations. + +**Best snippet** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Provides the closest context regarding creating a new Series from an existing Series 's', though it uses arithmetic rather than string logic. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Provides the closest context regarding creating a new Series from an existing Series 's', though it uses arithmetic rather than string logic. +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Demonstrates the concept of extracting a specific part of a string based on a format (TLD from a URL), which is conceptually similar to extracting the municipality. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why excluded: This is the exact same question, covering the same municipality/province data format and identifying .map() as the solution. + +### trial-final-exam-solutions-introduction-to-python-3077951-q09 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `9` +- Topic: 8-datetime-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Take a look at the following code segment. + +from datetime import datetime + +def get_months(date_strings): + dates = [] + for date_str in date_strings: + if "-" in date_str: + dates.append(datetime.strptime(date_str, "%d-%m-%Y")) + elif "/" in date_str: + dates.append(datetime.strptime(date_str, "%m/%d/%Y")) + else: + dates.append(None) + return [date.month if date is not None else None for date in dates] + +Suppose that you call the function like this: +get_months(["03/02/2013", "03.02.2013", "03-02-2013"]) + +What does the function call return? + +**Options** +- `a`: [3, None, 2] +- `b`: [2, None, 3] +- `c`: [3, 2] +- `d`: [2, 3] + +**Correct answer:** `a` + +**Official explanation:** "03/02/2013" matches %m/%d/%Y and gives month 3, "03.02.2013" matches neither branch and becomes None, and "03-02-2013" matches %d-%m-%Y and gives month 2. + +**Why not certain:** Excluding the near-identical past exam piece, there is no information in the library explaining the 'datetime' module, 'strptime' format codes (%d, %m, %Y), or the '.month' attribute. A student with zero prior knowledge could understand the loop and 'if/elif/else' structure, but would have no way to determine what the 'strptime' calls return or what '.month' refers to. + +**Gap summary:** The library relies entirely on a specific past exam question to answer this topic. There are no general concepts covering the 'datetime' library or advanced list comprehension syntax. + +**Missing concepts:** datetime.strptime() function and its behavior; Datetime format codes like %d (day), %m (month), %Y (year); Attributes of datetime objects such as .month; List comprehension with inline if-else syntax: [x if cond else y for x in list] +**Suggested fix:** Add a general 'Datetime' snippet covering parsing and attributes, and a 'List Comprehensions' snippet covering conditional logic. + +**Best snippet** +- `exam-trial_midterm-6-w2-conditions`: Conditions [w2-conditions] + Why: This snippet is the best structural match, demonstrating the pattern of iterating through a list, applying conditional logic inside a loop, and appending results to a new list. + +**Top 3 snippets** +- `exam-trial_midterm-6-w2-conditions`: Conditions [w2-conditions] + Why: This snippet is the best structural match, demonstrating the pattern of iterating through a list, applying conditional logic inside a loop, and appending results to a new list. +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Shows a function taking a string input and performing a check for specific characters (dashes), which helps understand the conditional branches in the question. + +**Minimal sufficient snippets** +- `exam-trial_midterm-6-w2-conditions`: Conditions [w2-conditions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-9-w6-datetime`: Datetime [w6-datetime] + Why excluded: This snippet contains the exact same code, function call, and explanation of the date parsing logic for the specific date strings provided. + +### trial-final-exam-solutions-introduction-to-python-3077951-q10 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `10` +- Topic: 8-datetime-2 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +Suppose that you want to write a function called day_of_year that takes a datetime value and returns the number of the day that the datetime value represents within the year. The return value is therefore always an integer between 1 and 366. + +For example, the function call: +day_of_year(datetime(2022, 2, 1)) +should return the integer: +32 + +Which of the following code segments will achieve what you want? (You can assume that the datetime and timedelta classes are already imported from the datetime module.) + +**Options** +- `a`: def day_of_year(dt): + return (dt - datetime(dt.year, 1, 1)).days + 1 +- `b`: def day_of_year(dt): + return timedelta(dt - datetime(dt.year, 1, 1)) + 1 +- `c`: def day_of_year(dt): + return dt - datetime(dt.year, 1, 1) + 1 +- `d`: def day_of_year(dt): + return (dt - datetime(dt.year, 1, 0)).days + +**Correct answer:** `a` + +**Official explanation:** Subtracting January 1 of the same year gives the zero-based offset in days, and adding 1 converts it to the day number within the year. The other options either return or manipulate timedeltas incorrectly or use an invalid date. + +**Why not certain:** Excluding the identical exam piece, the current snippets offer no guidance on datetime arithmetic, resulting types (timedelta), or why integer addition to a timedelta fails. A student without prior knowledge cannot differentiate between options a, b, and c. + +**Gap summary:** The snippet database lacks general-purpose documentation for the datetime module, particularly regarding subtraction and timedelta properties. + +**Missing concepts:** Datetime subtraction returns a timedelta; Using .days to extract an integer from a timedelta; Incompatibility of timedelta and integer addition; datetime constructor constraints (day must be > 0) +**Suggested fix:** Add a foundational snippet covering datetime arithmetic and the timedelta class. + +**Best snippet** +- ``: + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Shows basic function definition syntax which matches the required day_of_year(dt) structure, though it lacks the relevant datetime logic. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why excluded: This piece contains the exact same question and explanation, explicitly stating that datetime subtraction yields a timedelta, the .days attribute is needed to get an integer, and adding 1 is required for the day number. + +### trial-final-exam-solutions-introduction-to-python-3077951-q11 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `11` +- Topic: 8-dict_comprehension-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have a list of strings called list_1, in which every element is unique. + +Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key? + +**Options** +- `a`: {item: len(item) for item in list_1} +- `b`: [len(item) for item in list_1] +- `c`: {item for item in list_1 if len(item) > 0} +- `d`: {len(item): item for item in list_1} + +**Correct answer:** `a` + +**Official explanation:** Option A is the dictionary comprehension that maps each string to its length. Option B creates a list, option C creates a set, and option D reverses the intended key-value relation. + +**Why not certain:** While the near-identical pieces provide the answer directly, the general snippets do not explain the 'comprehension' syntax ({key: value for item in list}). A student with zero knowledge would know a dictionary uses {k:v} but wouldn't necessarily understand the 'for item in list_1' part inside the braces. + +**Gap summary:** Missing a general explanation of dictionary and list comprehension syntax. + +**Missing concepts:** dictionary comprehension syntax; list comprehension syntax +**Suggested fix:** Add a foundational snippet explaining the structure of comprehensions (e.g., '{key_expr: value_expr for item in iterable}'). + +**Best snippet** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet shows the literal structure of a dictionary '{1: 'I', 2: 'II'}', which helps a student recognize that dictionaries use curly braces and key:value pairs separated by colons. + +**Top 3 snippets** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet shows the literal structure of a dictionary '{1: 'I', 2: 'II'}', which helps a student recognize that dictionaries use curly braces and key:value pairs separated by colons. +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Reiterates the terminology of keys and values in the context of creating a dictionary. + +**Minimal sufficient snippets** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why excluded: This is the exact same question, options, and explanation as the current question. +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why excluded: This is a near-identical question using different variable names (words instead of list_1) but the same logic and target output. + +### trial-final-exam-solutions-introduction-to-python-3077951-q12 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `12` +- Topic: 8-list_comprehension-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +Suppose that you have a list of letters called list_1. Some letters are upper case, others are in lower case. + +You'd like to create another list that contains the same letters in the same order, but you want to turn every upper case letter into its lower case version, and every lower case letter into its upper case version. + +Which of the following code lines will achieve what you want? + +**Options** +- `a`: [letter.upper() if letter.islower() else letter.lower() for letter in list_1] +- `b`: [letter.upper() for letter in list_1 if letter.islower() else letter.lower()] +- `c`: [letter.lower() for letter in list_1 if letter.isupper()] + [letter.upper() for letter in list_1 if letter.islower()] +- `d`: [letter.capitalize() for letter in list_1 if not letter.iscapitalized()] + +**Correct answer:** `a` + +**Official explanation:** Option A flips the case of each letter while preserving the original order of the list. The other options either have invalid comprehension syntax, change the order, or use a non-existent string method. + +**Why not certain:** None of the candidate snippets cover the fundamental syntax of list comprehensions, nor the ternary operator (if-else) used within them. Furthermore, specific string methods like .upper(), .lower(), and .islower() are not documented in the provided snippets. + +**Gap summary:** The snippets provide no information on list comprehension syntax or conditional logic within comprehensions. + +**Missing concepts:** List comprehension basic syntax: [expression for item in list]; Ternary operator/Conditional comprehension: [val_if_true if condition else val_if_false for item in list]; String methods: .upper(), .lower(), .islower(), .isupper() +**Suggested fix:** Add a snippet family explaining list comprehensions, specifically highlighting the syntax for conditional values (ternary if-else) versus conditional filtering. + +**Best snippet** +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet is the only one that mentions the concept of upper and lower case letters ('Upper case and lower case versions of a letter count as'), which is relevant to the problem's domain, even though it does not provide the necessary code syntax. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: This snippet is the only one that mentions the concept of upper and lower case letters ('Upper case and lower case versions of a letter count as'), which is relevant to the problem's domain, even though it does not provide the necessary code syntax. +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Shows basic string input handling, though focused on phone numbers rather than case manipulation. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### trial-final-exam-solutions-introduction-to-python-3077951-q14 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `14` +- Topic: Basic loop +- Status: **insufficient** +- Confidence: `medium` + +**Question** + +You need to write a simple loop that iterates over the integers from 1 to 10, and in each iteration, prints the sum of the current and the previous number. In the first iteration, just take the previous number to be 0. + +For example: +1 + 0 = 1 +2 + 1 = 3 +3 + 2 = 5 +... +10 + 9 = 19 + +Choose the program that will print the correct output (i.e. only the sums). + +**Options** +- `a`: previous = 0 +for i in range(1, 11): + print(i + previous) + previous = i +- `b`: i = 0 +while i <= 10: + print(i + (i - 1)) + i += 1 +- `c`: Both of the above +- `d`: Neither of the above + +**Correct answer:** `a` + +**Official explanation:** A keeps track of the previous number and prints each sum correctly from 1 + 0 through 10 + 9. B does not use the required previous-value logic and prints the wrong sums. + +**Why not certain:** While an identical past exam snippet exists, its internal explanation is contradictory (it mentions Option B is correct while the code context and answer key indicate A). Furthermore, there are no snippets explaining the critical 'range(1, 11)' boundary behavior or the general syntax of 'for' vs 'while' loops for a student with zero Python knowledge. + +**Gap summary:** The snippet bank lacks foundational documentation on loop iteration and the range function. + +**Missing concepts:** range(start, stop) inclusive/exclusive bounds; Basic for-loop vs while-loop mechanics; State-tracking patterns (accumulating or referencing previous values) within a loop body +**Suggested fix:** Add a 'Loop Fundamentals' snippet that explains how range(1, 11) produces numbers 1-10 and illustrates how to update a state variable like 'previous' at the end of each iteration. + +**Best snippet** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Excluding the identical piece, this is the only other snippet that focuses on the concept of 'computing the sum of values,' which is a core part of the question's logic. + +**Top 3 snippets** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Excluding the identical piece, this is the only other snippet that focuses on the concept of 'computing the sum of values,' which is a core part of the question's logic. +- `exam-extra_practice-10-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why: Deals with pairs of numbers adding up to a target, which introduces the logic of relationships between multiple integers. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-14-w2-loops`: Loops [w2-loops] + Why excluded: This is an exact match for the question regarding summing the current and previous number in a loop from 1 to 10. + +### trial-final-exam-solutions-introduction-to-python-3077951-q16 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `16` +- Topic: List lambda +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You already have a list named list_1 with 2 lambda functions as follows: + +list_1 = [lambda a, b: a + b, lambda a, b: a * b] + +What would be printed by the following code snippet? +print(list_1[0](1, 2) ** list_1[1](1, 2)) + +**Options** +- `a`: 6 +- `b`: 7 +- `c`: 8 +- `d`: 9 + +**Correct answer:** `d` + +**Official explanation:** list_1[0](1, 2) returns 3 and list_1[1](1, 2) returns 2, so the expression becomes 3 ** 2, which is 9. + +**Why not certain:** While the exponentiation operator and function arguments are covered in other snippets, the 'lambda' keyword and the specific syntax of calling a function stored inside a list index are not explained anywhere except in the near-identical past exam piece. + +**Gap summary:** The primary gap is the definition and syntax of lambda functions and the concept of first-class functions (storing and calling functions from a list). + +**Missing concepts:** lambda functions; storing functions in lists; calling functions via list indexing syntax: list[index](args) +**Suggested fix:** Add a snippet or piece that explains that 'lambda' creates a small anonymous function and shows how a list of functions can be accessed and called using parentheses immediately after the index. + +**Best snippet** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why: This family is the only other one dealing with higher-order functions (functions in a list context) and explicitly demonstrates the exponentiation operator (**), which is critical for the final calculation. + +**Top 3 snippets** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why: This family is the only other one dealing with higher-order functions (functions in a list context) and explicitly demonstrates the exponentiation operator (**), which is critical for the final calculation. +- `exam-Resit 22/23-4-w3-arguments`: Arguments [w3-arguments] + Why: Explains how functions take integers as arguments and are called, which helps interpret the list_1[0](1, 2) syntax as a function call. + +**Minimal sufficient snippets** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] +- `exam-Resit 22/23-4-w3-arguments`: Arguments [w3-arguments] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why excluded: This piece contains the exact code and question from the current exam, providing the full solution and explanation. + +### trial-final-exam-solutions-introduction-to-python-3077951-q19 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `19` +- Topic: trial-dictionary-1 +- Status: **insufficient** +- Confidence: `low` + +**Question** + +You have to write a function called main that accepts a dictionary as an input argument. Both the keys and the values of the input are integers. + +Return another dictionary that has the same keys as the input argument. For each output key, the corresponding value should be calculated as the sum of those values from the input dictionary, whose keys are smaller than, or equal to, the output key in question. + +For example: +main({5: 1, 2: 5, 4: 2}) +should return a dictionary that is equal to: +{5: 8, 2: 5, 4: 7} + +Which of the following programs works as intended? + +**Options** +- `a`: def main(d1): + running_total = 0 + d2 = {} + for key in sorted(d1.keys()): + running_total += d1[key] + d2[key] = running_total + return d2 +- `b`: def main(d): + result = {} + for output_key in d.keys(): + result[output_key] = sum([v for k, v in d.items() if k <= output_key]) + return result +- `c`: Both of the above works as intended +- `d`: None of the above work as intended + +**Correct answer:** `c` + +**Official explanation:** Option A builds cumulative sums over the sorted keys, and option B directly computes the sum of values whose keys are less than or equal to each output key. Both produce the intended dictionary values. + +**Why not certain:** While existing snippets show dictionary creation and basic summing, they do not explain 'sorted(d.keys())' or the conditional logic 'if k <= output_key' inside a list comprehension. A student without prior knowledge would not know how dictionary keys are ordered by default or how to filter them based on size. + +**Gap summary:** Missing concepts of dictionary key sorting and conditional filtering during iteration. + +**Missing concepts:** sorted() on dictionary keys; conditional list comprehensions; cumulative sum logic (running totals) +**Suggested fix:** Add a snippet demonstrating how to process dictionary entries based on key comparisons or a sorted sequence. + +**Best snippet** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows the basic pattern of iterating through data to build a dictionary mapping keys to calculated values, which is the core structure of both options. + +**Top 3 snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows the basic pattern of iterating through data to build a dictionary mapping keys to calculated values, which is the core structure of both options. +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Demonstrates a dictionary with numeric values and the need to perform arithmetic (average/sum) on those values. +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Shows a function returning the sum of multiple values, which helps a student understand the 'sum()' part of Option B. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### trial-final-exam-solutions-introduction-to-python-3077951-q24 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `24` +- Topic: trial-functions-3 +- Status: **insufficient** +- Confidence: `high` + +**Question** + +If you know the radius r of a circle and you want to calculate its area, you need the value of pi from the math package and apply the formula: +πr² + +Suppose that the variable r already contains the radius of the circle. Which script does not print the correct answer for the area? + +**Options** +- `a`: import math +print(math.pi * r ** 2) +- `b`: from math import pi +print(pi * r ** 2) +- `c`: import math as constants +print(math.pi * r ** 2) +- `d`: from math import pi as constant +print(constant * r ** 2) + +**Correct answer:** `c` + +**Official explanation:** Option C imports the module under the name `constants`, but then tries to access `math.pi`, where `math` is not defined. The other options all reference pi correctly and would print the correct area. + +**Why not certain:** Excluding the near-identical past exam piece, none of the candidate snippets explain Python import mechanisms or how aliasing a module with 'as' affects access to its attributes. A student without prior knowledge would not know why option C is incorrect. + +**Gap summary:** There is a total lack of foundational material regarding imports and namespaces in the candidate set. + +**Missing concepts:** import as ; from import ; attribute access (dot notation) +**Suggested fix:** Add a summary snippet that demonstrates the four common import styles: 'import math', 'import math as m', 'from math import pi', and 'from math import pi as p'. + +**Best snippet** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why: This snippet provides the syntax for the exponentiation operator (**2), which is necessary to understand the radius squared part of the area formula (πr²). + +**Top 3 snippets** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] + Why: This snippet provides the syntax for the exponentiation operator (**2), which is necessary to understand the radius squared part of the area formula (πr²). +- `exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why: Briefly mentions variable context, which is relevant as the question assumes a variable 'r' is already defined. + +**Minimal sufficient snippets** +- `exam-midterm_2023-13-w3-higher-order-patterns`: Higher-Order Patterns [w3-higher-order-patterns] +- `exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-24-w2-conditions`: Functions and Imports [w1-functions-and-imports] + Why excluded: This piece is an exact duplicate of the current question, including the correct answer (C) and a clear explanation of the module aliasing logic. + +## Partial Questions + +Count: **36** + +### final-exam-solutions-for-python-programming-62oop21-q07 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `7` +- Topic: 7-pandas-3 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have a pandas DataFrame called df that looks like this, when printed: + + A B C D +1 8.7 4.6 9.5 7.0 +2 7.3 1.5 6.3 7.1 +3 4.3 9.0 2.9 3.3 +4 4.8 2.5 5.1 3.0 +5 1.6 1.4 6.7 3.5 +6 2.4 3.7 7.6 1.3 + +Suppose that you'd like to create a new Series that only contains those elements of column "D" of df that are smaller than 5.0. So the Series should look like this, when printed: + +3 3.3 +4 3.0 +5 3.5 +6 1.3 +Name: D, dtype: float64 + +Which of the following code lines will not achieve what you want? + +**Options** +- `a`: df.loc[2:6, df.columns[-1]] +- `b`: df.loc[df["D"] < 5, "D"] +- `c`: df.loc[3:6, "D"] +- `d`: df.iloc[2:6, 3] + +**Correct answer:** `a` + +**Official explanation:** Option A slices rows 2 through 6 from the last column but does not filter out values that are 5.0 or larger, so it includes values that should not be in the result. + +**Why not certain:** While the snippets show examples of pandas syntax, they do not explicitly define the rules for .loc (label-based, inclusive) vs .iloc (integer-based, exclusive) or how negative indexing works with columns, which are critical for distinguishing option A from the others. + +**Gap summary:** The snippets provide examples but lack a conceptual summary of pandas selection methods (.loc vs .iloc) and boolean indexing logic. + +**Missing concepts:** Label-based vs Integer-based indexing (.loc vs .iloc); Boolean indexing/filtering in Pandas; Slicing behavior (inclusive vs exclusive) in .loc and .iloc; Negative column indexing using df.columns[-1] +**Suggested fix:** Add a summary snippet for 'Pandas Inspecting and Selecting Data' that explicitly compares .loc and .iloc with examples of slicing and boolean masks. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question. +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows basic DataFrame column access and vectorized operations, helping the student understand DataFrame syntax. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why excluded: This piece uses the exact same DataFrame structure and a nearly identical problem statement about selecting data from column 'D'. + +### final-exam-solutions-for-python-programming-62oop21-q09 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `9` +- Topic: 8-comprehensions-1 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have a list of mountain peaks and their heights in meters, all formatted as "[PEAK NAME]: [HEIGHT]m". For example, a few elements of the list are: +"Denali: 6,190m", "Aconcagua: 6,961m", "Kilimanjaro: 5,895m", ... + +As you can see, the comma (",") is used as a thousand separator in the height. The list is called mountains. + +You'd like to create a dictionary called peaks from the mountains list. The peak names would be the keys, and the corresponding integer values. Continuing the example above, a few key-value pairs of the peaks dictionary should be: +"Denali": 6190, "Aconcagua": 6961, "Kilimanjaro": 5895, ... + +Which of the following two code segments achieves what you want? + +**Options** +- `a`: peaks = {peak.split(":")[0]: int(peak.split(": ")[1][:-1].replace(",", "")) for peak in mountains} +- `b`: names = [peak.split(":")[0] for peak in mountains] +heights = [int(peak.split(": ")[1].replace(",", "").replace("m", "")) for peak in mountains] +peaks = dict(zip(names, heights)) +- `c`: Both code segments above achieve the intended outcome. +- `d`: Neither of the two code segments above achieves the intended outcome. + +**Correct answer:** `c` + +**Official explanation:** Both solutions strip off the trailing m, remove the thousands separator, convert the height to an integer, and pair each mountain name with its numeric height. + +**Why not certain:** The snippets provide strong structural evidence that both Code Segment A (dictionary comprehension) and Code Segment B (zip/dict) are valid Python patterns for creating dictionaries. However, a student with zero prior knowledge would still struggle to verify the 'string cleaning' logic (split, replace, slicing) as none of the snippets explicitly show these methods in action. + +**Gap summary:** Structural dictionary patterns are well-covered, but the specific string manipulation methods required to 'clean' the data are missing. + +**Missing concepts:** String .split() method; String .replace() method; String slicing syntax (e.g., [:-1]); The use of int() for converting numeric strings +**Suggested fix:** Add a reference snippet or past exam item that explicitly uses .split(), .replace(), and slicing to parse strings. + +**Best snippet** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A. + +**Top 3 snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A. +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Demonstrates creating a dictionary from two separate lists (names and values), which confirms the validity of the structural pattern used in Option B. +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Provides a conceptual precedent for extracting specific substrings (like a TLD) from a larger formatted string, mirroring the task of parsing names and heights. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q10 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `10` +- Topic: 8-comprehensions-2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have a dictionary called grades, in which the keys are unique student ID's (as strings) and the corresponding values are each student's Python course grades (as floats). + +You'd like to create another dictionary called grade_curve, in which the keys are the 18 possible Dutch course grades (1.0, 1.5, 2.0, ..., 10) as floats, and the corresponding (integer) values are the number of students in grades who have that particular grade. + +Take a look at the following code segment to create the grade_curve dictionary. + +dutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, + 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0] +grade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades} + +Do you think this code segment will always work as intended? If not, then why not? + +**Options** +- `a`: Yes, the code will always work as intended. +- `b`: The code will not work as intended if there are certain grades that no student has received. That will lead to an error in constructing the dictionary comprehension. +- `c`: The code will not work as intended, because the keys of the grades dictionary are not used in the list comprehension inside the sum function. +- `d`: The code will not work as intended, because including a list comprehension inside a dictionary comprehension will lead to a Python syntax error. + +**Correct answer:** `a` + +**Official explanation:** The inner comparison list produces True and False values for every grade entry, and sum counts the matches, including zero when no student received that grade. + +**Why not certain:** The snippets show that dictionary comprehensions are a standard and valid way to count items or transform lists into dictionaries. However, none explicitly explain that 'sum()' on a list of booleans converts True to 1 and False to 0, which is the specific mechanism used in the question's code. + +**Gap summary:** The snippets confirm that the syntax is valid (ruling out d) and that dictionary counting is a common pattern. However, the specific behavior of sum() with booleans and the fact that an empty match returns 0 rather than an error is not explicitly covered. + +**Missing concepts:** sum() behavior with Boolean values (True=1, False=0); Behavior of comprehensions when no items match a condition (returns 0 for sum of empty/false list) +**Suggested fix:** Add a snippet or detail explaining how Python handles boolean arithmetic and summing lists of comparison results. + +**Best snippet** +- `exam-extra_practice-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question. + +**Top 3 snippets** +- `exam-extra_practice-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question. +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Demonstrates the syntax and validity of dictionary comprehensions, which helps rule out option (d). +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Provides another example of generating a dictionary from a sequence using logic in a comprehension. + +**Minimal sufficient snippets** +- `exam-extra_practice-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-solutions-for-python-programming-62oop21-q20 + +- Exam: `final-exam-solutions-for-python-programming-62oop21` +- Question number: `20` +- Topic: final-functions-2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +Take a look at the following function definition. + +What will be returned by the following function call: +glue(a='e', b='d') + +**Options** +- `a`: ab +- `b`: cd +- `c`: ba +- `d`: dc + +**Correct answer:** `c` + +**Official explanation:** The function iterates over the keyword names in insertion order (`a`, then `b`) and prepends each key to the current result. Starting from the empty string, that produces `a`, then `ba`. + +**Why not certain:** The snippets explain that **kwargs handles multiple keyword arguments and show how loops iterate over keys. However, they do not explicitly state that the 'keys' in **kwargs are the argument names (the strings 'a' and 'b') or that Python preserves the insertion order of these arguments, which is critical to deciding between 'ab' and 'ba'. + +**Gap summary:** There is no explicit explanation that **kwargs keys map to the argument names and follow the order of the function call. + +**Missing concepts:** **kwargs dictionary mapping (parameter names as keys); Keyword argument insertion order preservation; Behavior of .keys() on a **kwargs object +**Suggested fix:** Add a snippet clarifying that **kwargs collects parameters into a dictionary where the names (the left side of the '=') are keys, and that they are processed in the order they appear in the call. + +**Best snippet** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents. + +**Top 3 snippets** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents. +- `exam-midterm_2024-18-w2-loops`: Loops [w2-loops] + Why: Demonstrates the syntax for iterating over keys in a dictionary-like structure (for key in x), which is essential for tracing the 'for el in kwargs.keys()' loop. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] +- `exam-midterm_2024-18-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q03 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `3` +- Topic: 1_Basics_Variables_1 +- Status: **partial** +- Confidence: `high` + +**Question** + +What is the output of the following code segment? + +**Options** +- `a`: [str, int, NoneType, bool, float, str, dict] +- `b`: [str, int, NoneType, bool, float, bool, dict] +- `c`: [str, int, NoneType, bool, float, str, list] +- `d`: [str, float, NoneType, bool, int, str, dict] + +**Correct answer:** `a` + +**Official explanation:** The function appends the type of each element in the input list in order: string, integer, NoneType, boolean, float, string, and dictionary. + +**Why not certain:** The general snippets cover str, int, bool, float, and dict. However, 'NoneType' is missing from all lecture snippets, and the 'type()' function is not explicitly defined outside of exam context explanations. The 'False' string vs. boolean distinction is also only explicitly clarified in the near-identical exam piece. + +**Gap summary:** Lecture snippets define the names of types but lack examples for 'None/NoneType' and do not explicitly define the 'type()' function. + +**Missing concepts:** NoneType; type() function behavior +**Suggested fix:** Add 'None' to the '8 types to know' lecture snippet and include a small section explaining that 'type(x)' returns the type name of object x. + +**Best snippet** +- `ks-cb3a9e3fd2`: Objects and Names [w1-objects-and-names] + Why: Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner. + +**Top 3 snippets** +- `ks-cb3a9e3fd2`: Objects and Names [w1-objects-and-names] + Why: Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner. +- `ks-eae9bf47dd`: Objects and Names [w1-objects-and-names] + Why: Confirms that 'dict' is one of the standard Python types, which is necessary to identify the {} element. + +**Minimal sufficient snippets** +- `ks-cb3a9e3fd2`: Objects and Names [w1-objects-and-names] +- `ks-eae9bf47dd`: Objects and Names [w1-objects-and-names] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why excluded: This piece contains the exact same code elements ('abc', 0, None, True, 123.456, 'False', {}) and explicitly maps them to their types, including the 'None' to 'NoneType' mapping and the 'False' in quotes as 'str' distinction. + +### final-exam-study-guide-trial-python-basics-2023-q04 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `4` +- Topic: 2-dictionaries - comprehension - 1 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values. + +The ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters. + +That is, if we execute the following command: +print(vowels_ASCII) + +the output should be: +{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117} + +Which of the code segments work(s) as intended? + +Hint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value. + +For example: +ord('a') + +returns: +97 + +**Options** +- `a`: vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou'} +- `b`: vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou' if vowel in 'aeiou'} +- `c`: Both of the code segments work correctly. +- `d`: Neither of the code segments work correctly. + +**Correct answer:** `c` + +**Official explanation:** Both comprehensions produce the same dictionary because the extra condition in option B is always true for characters drawn from 'aeiou'. + +**Why not certain:** While the identical question prompt is found, the snippets themselves are truncated and do not show the full code solutions or explanations for the 'ord()' function and dictionary comprehension syntax. A student with zero knowledge would see the pattern but lack the specific function definitions. + +**Gap summary:** The snippets provide examples of the desired output and similar problems, but lack the foundational syntax for dictionary comprehensions and the definition of the 'ord()' function. + +**Missing concepts:** Dictionary comprehension syntax {k: v for x in iterable}; ord() function purpose and usage; Effect of redundant 'if' conditions in comprehensions +**Suggested fix:** Add a conceptual snippet from Week 2 lecture materials that explains dictionary comprehensions and common built-in functions like ord(). + +**Best snippet** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure. + +**Top 3 snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure. +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Demonstrates dictionary creation with an 'if' filtering clause, which is relevant to evaluating Option B. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why excluded: This piece contains the exact same question prompt about creating the 'vowels_ASCII' dictionary. + +### final-exam-study-guide-trial-python-basics-2023-q07 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `7` +- Topic: 2-list - comprehension - 2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +What is the output of the following code segment? + +**Options** +- `a`: [1, 4, 3, 8, 5] +- `b`: [2, 4, 6, 8, 10] +- `c`: [1, 2, 3, 4, 5] +- `d`: [2, 2, 6, 4, 10] + +**Correct answer:** `a` + +**Official explanation:** The list comprehension doubles only the even numbers and leaves the odd numbers unchanged, so the result is [1, 4, 3, 8, 5]. + +**Why not certain:** The snippets explain 'list comprehension' and the even-number check (% 2 == 0). However, they do not explain the ternary 'if-else' syntax within a comprehension (val if cond else other), which is the specific mapping logic used here. A student would have to infer that 'if' applies to the preceding expression. + +**Gap summary:** The candidate snippets cover list comprehensions with filters ([x for x in list if cond]) but lack examples of conditional mapping ([val_if if cond else val_else for x in list]). + +**Missing concepts:** ternary operator / conditional expression syntax; conditional mapping in list comprehensions +**Suggested fix:** Add a snippet or piece that explains the 'value if condition else other_value' syntax, specifically within a list comprehension context. + +**Best snippet** +- `exam-trial-final-exam-py22-7-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question. + +**Top 3 snippets** +- `exam-trial-final-exam-py22-7-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question. +- `exam-midterm_2024-3-w2-loops`: Loops [w2-loops] + Why: Reinforces the logic of the modulo operator (i % 2 == 0) in a different context (while loops), helping a student confirm that this expression identifies even numbers. + +**Minimal sufficient snippets** +- `exam-trial-final-exam-py22-7-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] +- `exam-midterm_2024-3-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q08 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `8` +- Topic: 2-list - manipulation - 2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +What is the output of the following code segment? + +**Options** +- `a`: ['10a', '30c'] +- `b`: [10, 20, 30, 40] +- `c`: ['a', 'b', 'c', 'd'] +- `d`: ['10a', '20b', '30c', '40d'] + +**Correct answer:** `a` + +**Official explanation:** The loop keeps only even indices from enumerate(list1), so it uses indices 0 and 2 and appends the concatenated strings '10a' and '30c'. + +**Why not certain:** The snippets cover the modulo operator and list appending, but there is no explanation of the enumerate() function, which is critical for knowing that the loop variable 'index' refers to the position and 'value' refers to the content. + +**Gap summary:** The primary gap is the lack of information regarding the enumerate() function and the behavior of string concatenation with converted integers. + +**Missing concepts:** enumerate() function behavior; string concatenation (str(value) + list2[index]) +**Suggested fix:** Add a snippet or AI question entry explaining that enumerate(list) provides pairs of (index, value) during iteration. + +**Best snippet** +- `exam-midterm_2024-3-w2-loops`: Loops [w2-loops] + Why: This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question. + +**Top 3 snippets** +- `exam-midterm_2024-3-w2-loops`: Loops [w2-loops] + Why: This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question. +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Provides an example of the .append() method, which is used to build the result list in the code segment. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: While focused on DataFrames, the rationale explains the concept of using a 'boolean mask on the index to find even numbers', reinforcing the parity selection logic. + +**Minimal sufficient snippets** +- `exam-midterm_2024-3-w2-loops`: Loops [w2-loops] + Why: Necessary for understanding the % parity operator. +- `exam-midterm_2023-16-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Necessary for understanding how append adds items to a list. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q09 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `9` +- Topic: 2-list - slicing - 2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +Suppose you have a list called mylist. You want to extract every third element starting from index 1 (inclusive) to the last index (inclusive) from that list using the following line of code: +subset = mylist[___:___:___] + +For example, if you have: +mylist = [10, 15, 20, 25, 30, 35, 40, 45] + +then executing the following command: +print(subset) + +should return: +[15, 30, 45] + +What should the blanks be filled with? + +**Options** +- `a`: 1:len(mylist):3 +- `b`: 0:len(mylist):3 +- `c`: 1:len(mylist)-1:3 +- `d`: 0:len(mylist)-1:3 + +**Correct answer:** `a` + +**Official explanation:** Starting at index 1 and stepping by 3 gives positions 1, 4, and 7, which are 15, 30, and 45. Using len(mylist) as the stop value includes the last valid stepped element. + +**Why not certain:** The necessary concepts (start position, step size, and 'stop' exclusion) are all present in the aiq-3 family. However, a student must synthesize the 'stop is excluded' rule from the range() piece and apply it to the slicing examples, as there isn't a single piece that defines the full [start:stop:step] syntax in one rule. + +**Gap summary:** The snippets lack a direct definition of the three-part list slicing syntax [start:stop:step] in a unified rule. + +**Missing concepts:** Explicit definition of the list[start:stop:step] syntax; Direct rule stating that for slicing, index 'stop' is excluded +**Suggested fix:** Add a foundational snippet explaining list[start:stop:step] where start is inclusive, stop is exclusive, and step is the increment. + +**Best snippet** +- `aiq-3`: Comprehensions [w6-comprehensions] + Why: This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded. + +**Top 3 snippets** +- `aiq-3`: Comprehensions [w6-comprehensions] + Why: This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded. + +**Minimal sufficient snippets** +- `aiq-3`: Comprehensions [w6-comprehensions] + Why: It is the only family in the candidate set that provides examples of list stepping and explains index-based exclusion logic. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q11 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `11` +- Topic: 3_Function_Built-in_3 +- Status: **partial** +- Confidence: `medium` + +**Question** + +Suppose you have a variable called x which contains a list of integers as follows: +x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] + +Which of the following lines will produce an output that is different from the rest? + +**Options** +- `a`: print(len(x)) +- `b`: print(sorted(x, reverse=True)[0]) +- `c`: print(x.index(9)) +- `d`: print(sum(x[4:6])) + +**Correct answer:** `a` + +**Official explanation:** len(x) is 10, while sorted(x, reverse=True)[0] is 9, x.index(9) is 9, and sum(x[4:6]) is 4 + 5 = 9. + +**Why not certain:** While the snippets cover the complex `sorted` logic and provide context for slicing, they do not define the basic built-in functions `len()` and `sum()`, nor the list method `.index()`. A student with zero Python knowledge would have to rely on the English meaning of these words to guess their function. + +**Gap summary:** The snippets fail to define several fundamental built-in functions and list methods used in the question options. + +**Missing concepts:** len() function; sum() function; list.index() method +**Suggested fix:** Add a summary piece covering 'Common List Built-ins and Methods' that defines len, sum, and index. + +**Best snippet** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B. + +**Top 3 snippets** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B. +- `exam-Resit 22/23-5-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Reinforces the explanation of reverse sorting and basic list operations. +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + Why: Provides an example of slicing syntax (`alphabet[1::2]`), which helps a student interpret the `x[4:6]` slice in option D. + +**Minimal sufficient snippets** +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] +- `exam-midterm_2023-14-w2-loops`: Loops [w2-loops] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q16 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `16` +- Topic: 9_OOP_Easy_3 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following definition for a class called Shape: + +What would be the output if we execute the following commands? + +print(Shape(5, 3).area == Shape(1, 15).length) + +**Options** +- `a`: True +- `b`: False +- `c`: An error +- `d`: None of the given options. + +**Correct answer:** `a` + +**Official explanation:** `Shape(5, 3).area` is `5 * 3 = 15`, and `Shape(1, 15).length` is `15`, so the comparison evaluates to `True`. + +**Why not certain:** While the snippets explain class definition, initialization, and boolean output, they don't explicitly show the 'dot notation' (e.g., .area) being used directly on a newly created instance. A student must infer that Shape(5, 3).area refers to the attribute created inside __init__. + +**Gap summary:** The candidate snippets are mostly exam prompts rather than direct reference material. They provide enough clues for a logical student to infer the answer, but they lack a concise explanation of attribute access on instance objects. + +**Missing concepts:** Accessing attributes via dot notation on temporary instances; Explicit explanation of 'self' inside calculations in __init__ +**Suggested fix:** Add a foundational reference snippet that explains the lifecycle: Class Call -> __init__ execution -> Attribute storage -> Dot notation retrieval. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables. +- `exam-midterm_2024-2-w2-conditions`: Conditions [w2-conditions] + Why: Demonstrates the evaluation of equality (==) and logic in print statements, confirming that the output of such comparisons in Python is a boolean (True/False). +- `exam-Test Exam 07-06-22-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Shows the syntax for instantiating a class with multiple arguments (Flight(...)), which helps clarify the 'Shape(5, 3)' part of the question. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-midterm_2024-2-w2-conditions`: Conditions [w2-conditions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q17 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `17` +- Topic: 6-string - operations - 2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +Write a function called shuffle_sentence that takes a string as an argument and returns a new string where the words are shuffled randomly. + +For example, if your function is called as: +shuffle_sentence("Hello, how are you today?") +then it could return a shuffled string like: +'how today? you Hello, are' + +Which of the following programs work(s) according to the requirements? + +Hints: +The shuffle() function is a method from the random module. The shuffle() method takes a sequence, like a list, and reorganizes the order of the items. This method changes the original list; it does not return a new list. +The reversed() function computes the reverse of a given sequence object and returns it in the form of a list. + +**Options** +- `a`: def shuffle_sentence(sentence): + words = sentence.split() + return ' '.join(reversed(words)) +- `b`: import random + +def shuffle_sentence(sentence): + words = sentence.split() + random.shuffle(words) + return ' '.join(words) +- `c`: Both of the programs work. +- `d`: Neither of the programs work. + +**Correct answer:** `b` + +**Official explanation:** Option B is the only one that actually shuffles the words randomly. Option A only reverses the word order, which does not satisfy the random-shuffle requirement. + +**Why not certain:** The snippets help explain 'in-place mutation' and 'None return values', which are the 'traps' of the question. However, they do not provide any information on string split() or join() methods, which are required to understand the code structure. The question's internal hints are actually more helpful for the shuffle() behavior than the snippets. + +**Gap summary:** The snippets cover the logic of mutation but miss the specific string-list conversion methods used in both options. + +**Missing concepts:** str.split(); str.join(list) +**Suggested fix:** Add a snippet demonstrating how to convert a sentence into a list of words using split() and how to recombine them into a string using join(). + +**Best snippet** +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + Why: This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it). + +**Top 3 snippets** +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] + Why: This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it). +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'Return Behavior' piece explains that functions without an explicit return (or returning None) result in None, which helps clarify the hint that shuffle() does not return a new list. + +**Minimal sufficient snippets** +- `aiq-2`: Generators and Iterators [w6-generators-and-iterators] +- `aiq-4`: Comprehensions [w6-comprehensions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q23 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `23` +- Topic: 9_OOP_Function_2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following definition for a class called Employee: + +class Employee: + def __init__(self, name, role, salary): + self.name = name + self.role = role + self.salary = salary + # ... + +You want to add three methods to this class: +1. The holiday_bonus() method which computes and returns the holiday bonus, which is 8.0% of the yearly salary, +2. The year_end_bonus() method which computes and returns the year end bonus, which is 8.3% of the yearly salary +3. The payment_overview() method which returns a payment overview of the employee using the following format: +[Name] receives $[salary] monthly, $[holiday bonus] in May and $[year end bonus] in December. + +For example, if we execute the following commands: +employee1 = Employee('John Smith', 'HR representative', 2500) +print(employee1.holiday_bonus()) +print(employee1.year_end_bonus()) +print(employee1.payment_overview()) + +the output should be: +2400.0 +2490.0 +John Smith receives $2500 monthly, $2400.0 in May and $2490.0 in December. + +Which of the following code segments should you place on the blank in the class definition to achieve what you want? + +**Options** +- `a`: def holiday_bonus(self): + return self.salary * 12 * 0.080 +def year_end_bonus(self): + return self.salary * 12 * 0.083 +def payment_overview(self): + return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus()} in May and ${self.year_end_bonus()} in December.' +- `b`: def payment_overview(self): + return f'{self.name} receives ${self.salary} monthly, ${self.salary*12*0.08} in May and ${self.salary*12*0.083} in December.' +- `c`: def holiday_bonus(): + self.holiday_bonus = self.salary * 12 * 0.080 +def year_end_bonus(): + self.year_end_bonus = self.salary * 12 * 0.083 +def payment_overview(self): + return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.' +- `d`: def payment_overview(self): + self.holiday_bonus = self.salary * 12 * 0.080 + self.year_end_bonus = self.salary * 12 * 0.083 + return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.' + +**Correct answer:** `a` + +**Official explanation:** Option A defines all three requested methods, computes the two bonuses from the yearly salary, and uses those method results in the overview string. + +**Why not certain:** The snippets cover class structure, attribute access, and string formatting. However, they do not explicitly show a method calling another method within the same class using 'self.method()', which is the critical syntax required to distinguish Option A from the others. A student might not know if they should use parentheses or if variables like 'self.holiday_bonus' (Option C/D) are sufficient. + +**Gap summary:** Missing a clear example of 'internal method delegation'—where one instance method calls another instance method of the same object. + +**Missing concepts:** method-to-method calling syntax (self.method_name()); difference between instance attributes and instance methods +**Suggested fix:** Add an OOP snippet showing a class like 'Receipt' with a 'get_tax()' method and a 'get_total()' method that calls 'self.get_tax()'. + +**Best snippet** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides the foundational syntax for defining a class and initializing attributes (name, mode), helping the student understand the 'self' syntax and attribute access used in the Employee class. +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Demonstrates string formatting with variables and rounding, which is necessary for constructing the 'payment_overview' method return string. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### final-exam-study-guide-trial-python-basics-2023-q24 + +- Exam: `final-exam-study-guide-trial-python-basics-2023` +- Question number: `24` +- Topic: 9_OOP_Hard_2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following definitions for a class called Car: + +class Car: + def __init__(self, brand, model): + self.brand = brand + self.model = model + + def get_description(self): + return f"{self.brand}, {self.model}" + +You want to create another class called Garage, which has two attributes that are initialized during object construction: +- The 'capacity' attribute, which is an integer and must be passed to the object constructor. +- The 'cars' attribute, which is an empty list. + +The Garage class should also have two methods: +1. The add_car() method, which adds Car objects to a Garage object. New Car objects can only be added if there is still capacity in the Garage object. If not, the method should return "Capacity reached." +2. The check_garage() method, which reports the Car objects that have been added to the Garage object. The method should return a dictionary in which the keys are the counts of Car objects starting from 1 and the values are the Car objects' descriptions. + +For example, if we execute the following commands: +my_garage = Garage(2) +my_garage.add_car(Car("Toyota", "Camry")) +my_garage.add_car(Car("Honda", "Accord")) +print(my_garage.check_garage()) + +the output should be: +{1: 'Toyota, Camry', 2: 'Honda, Accord'} + +Which of the following code segments achieve(s) what you want? + +**Options** +- `a`: class Garage: + def __init__(self, capacity, cars = []): + self.capacity = capacity + + def add_car(self, car): + self.cars += car if len(self.cars) < self.capacity else return 'Capacity reached.' + + def check_garage(self, car): + return {index: car.get_description() for index, car in enumerate(self.cars, start=1)} +- `b`: class Garage: + def __init__(self, capacity): + self.capacity = capacity + self.cars = [] + + def add_car(self, car): + if len(self.cars) < self.capacity: + self.cars.append(car) + else: + return 'Capacity reached.' + + def check_garage(self): + output = {} + for index, car in enumerate(self.cars, start=1): + output[index] = car.get_description() + return output +- `c`: Both of the above will work. +- `d`: None of the above will work. + +**Correct answer:** `b` + +**Official explanation:** Option B initializes capacity and an empty cars list, appends cars only when capacity remains, returns the required message when full, and builds the requested dictionary in check_garage(). + +**Why not certain:** The snippets cover class structure, method definitions, and the target dictionary format. However, they lack specific examples of using 'enumerate' with a 'start' parameter and the 'list.append()' method, making it difficult for a student with zero knowledge to confidently select Option B over the syntactically incorrect Option A. + +**Gap summary:** The current snippets do not explain how to iterate with an index (enumerate) or how to properly add items to a list attribute (append). + +**Missing concepts:** enumerate() with start parameter; list.append() method; list concatenation vs appending (+= vs .append) +**Suggested fix:** Add a snippet from Week 2 or Week 4 materials that explicitly shows list appending and the use of enumerate() to build a dictionary from a list. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class. +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Demonstrates adding methods with internal logic and attribute comparisons to a class, helping the student understand how add_car() and check_garage() should be structured. +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows a dictionary with integer keys starting from 1, which matches the expected output format of the check_garage() method. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q04 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `4` +- Topic: 2-dictionaries - comprehension - 2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols. + +That is, if we execute the following command: +print(roman_nums) +the output should be: +{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'} + +Which of the following code segments works as intended? + +**Options** +- `a`: roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])} +- `b`: roman_nums = {roman: num for roman, num in zip(['I', 'II', 'III', 'IV', 'V'], range(1, 6))} +- `c`: roman_nums = {num: ['I', 'II', 'III', 'IV', 'V'][num] for num in range(1, 6)} +- `d`: roman_nums = {num: roman for num, roman in zip(range(1, 6), 'I II III IV V')} + +**Correct answer:** `a` + +**Official explanation:** Option A zips the integers 1 through 5 with the five Roman numeral strings and builds the required dictionary. The other options either reverse the keys and values, use incorrect indexing, or iterate over a plain string instead of the intended list of numerals. + +**Why not certain:** While the near-identical snippet provides the answer directly, the remaining candidate snippets only describe the logic of mapping lists to dictionaries without showing the actual Python implementation (zip, range, or comprehension syntax) in the search text. A student with zero knowledge would find it difficult to distinguish between the correct zip() usage and the incorrect string iteration in Option D. + +**Gap summary:** The candidate list is heavily reliant on past exam questions rather than syntax references. There is no piece explaining how zip() pairs items or that range(1, 6) excludes the number 6. + +**Missing concepts:** zip() function mechanics (pairing elements from two iterables); Dictionary comprehension syntax {k: v for ...}; range(start, stop) behavior (the stop value is exclusive); Difference between iterating over a list vs. a space-separated string +**Suggested fix:** Add a general reference snippet for 'Dictionary Comprehensions' and 'Common Iteration Utilities' that explicitly shows the syntax and examples of zip() and range(). + +**Best snippet** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here. + +**Top 3 snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here. +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows the scenario of creating a dictionary from two parallel lists (names and ages), which is the primary use case for the zip() function used in the correct answer. +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Another example of mapping keys to specific values (vowels to ASCII), helping the student recognize the pattern of building a mapping dictionary. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why excluded: This is the exact same question about creating the roman_nums dictionary using Roman numerals 1-5. + +### introduction-to-python-trial-final-exam-solutions-py22-q12 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `12` +- Topic: 3_Function_Flexible-Argument_2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You need to write a function called main which accepts a list of integers as an argument. The function should return a tuple of two integers, in which the first is the sum of the squares of all even numbers, and the second is the sum of the squares of all odd numbers. + +For example, calling the function as: +main(1, 2, 3, 4) +should return: +(20, 10) + +Which of the following blocks of code fits with the rest of the program and will you give the intended output? + +**Options** +- `a`: for i in args: + if i % 2 == 0: + total_even += i**2 + else: + total_odd += i**2 + +return (total_even, total_odd) +- `b`: for i in args: + if i % 2 == 1: + total_even += i + else: + total_odd += i + +return (total_even**2, total_odd**2) +- `c`: for i in args: + if i % 2 == 0: + total_even.append(i**2) + else: + total_odd.append(i**2) + +return (sum(total_even), sum(total_odd)) +- `d`: All of the given code blocks work as intended. + +**Correct answer:** `a` + +**Official explanation:** Option A directly accumulates the squares of even numbers and odd numbers into the two totals and returns them as the required tuple. + +**Why not certain:** The snippets provide the framework for flexible arguments (*args), iteration, and tuple returns. However, the student still needs to know the specific syntax for modulo (%) to check even/odd status and exponentiation (**) for squaring, which are not explicitly in these snippets. + +**Gap summary:** Missing explicit demonstration of basic Python arithmetic operators for parity checks and power calculations. + +**Missing concepts:** modulo operator (%) for parity checks; exponentiation operator (**) for squaring +**Suggested fix:** Add a snippet or key point covering arithmetic operators, specifically highlighting how to use % 2 to identify even/odd numbers and ** 2 to square values. + +**Best snippet** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question. + +**Top 3 snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question. +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: Specifically mentions a function (sum_even_integers) that accepts flexible arguments and performs parity filtering, directly mapping to the question's logic. +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Contains a reminder about tuple syntax, helping the student recognize that (total_even, total_odd) is a valid tuple return. + +**Minimal sufficient snippets** +- `aiq-4`: Comprehensions [w6-comprehensions] +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q15 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `15` +- Topic: 8_Datetime_Easy_3 +- Status: **partial** +- Confidence: `low` + +**Question** + +Which code segment gives the same output as the following: + +date1 = datetime(2023, 6, 1).strftime('%d-%m-%Y') +date2 = datetime(2023, 5, 1).strftime('%d-%m-%Y') +print((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days) + +You may assume that the datetime and timedelta classes are already imported from the datetime module. + +**Options** +- `a`: print((datetime(2023, 5, 1) - datetime(2023, 6, 1)).days) +- `b`: print((datetime(2023, 6, 1) - datetime(2023, 1, 5)).days) +- `c`: print((datetime.strptime('2023-6-1', '%Y-%d-%m') - datetime.strptime('2023-5-1', '%Y-%d-%m')).days) +- `d`: print((datetime.strptime('2023-06-01', '%Y-%m-%d') - datetime.strptime('2023-05-01', '%Y-%m-%d')).days) + +**Correct answer:** `d` + +**Official explanation:** Option D parses ISO-style date strings using the matching '%Y-%m-%d' format and subtracts the May date from the June date, giving the same day difference as the original code. + +**Why not certain:** The available snippets explain the result of datetime subtraction and the .days attribute, but they completely lack information on strftime, strptime, and the specific formatting codes (like %d, %m, %Y) used in both the question and the options. A student without prior knowledge would be guessing the meaning of the date strings and parsing logic. + +**Gap summary:** The main gap is the lack of documentation on date string parsing and formatting. + +**Missing concepts:** datetime.strptime; datetime.strftime; strftime/strptime format codes (%Y, %m, %d, %H, etc.) +**Suggested fix:** Add a lecture-style snippet or a comprehensive 'cheat sheet' piece that lists common datetime formatting codes and explains the difference between creating a string (strftime) and parsing a string (strptime). + +**Best snippet** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question. +- `ks-b6a39f66a2`: Functions and Imports [w1-functions-and-imports] + Why: Provides a very basic introduction to functions, which helps a novice understand that methods like strftime and strptime are groupings of code performing tasks. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q19 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `19` +- Topic: 7-pandas - hard - 2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +Consider the following pandas DataFrame called df, and assume that Pandas is already imported. + +You need to perform a series of operations on this DataFrame: +- Operation 1: Create a new column called Name_Length that contains the length of each person's name +- Operation 2: Replace all occurrences of the occupation 'Engineer' with 'Software Developer' +- Operation 3: Extract the last two characters of each person's name and store them in a new column called Name_Suffix + +Which of the following blocks of code performs these operations as intended? + +**Options** +- `a`: df['Name_Length'] = df['Name'].map(lambda x: len(x)) +df['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']] +df['Name_Suffix'] = df['Name'].map(lambda x: x[-2:]) +- `b`: df['Name_Length'] = len(df['Name']) +df['Occupation'] = ['Software Developer' if x == 'Engineer' else x for x in df['Occupation']] +df['Name_Suffix'] = df['Name'].lambda x: x[-2:] +- `c`: df['Name_Length'] = len(df['Name']) +df['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x) +df['Name_Suffix'] = df['Name'].map(lambda x: x[:-2]) +- `d`: df['Name_Length'] = df['Name'].map(len) +df['Occupation'] = df['Occupation'].map(lambda x: 'Software Developer' if x == 'Engineer' else x) +df['Name_Suffix'] = df['Name'].map(lambda x: x[-2:-1]) + +**Correct answer:** `a` + +**Official explanation:** Option A correctly maps each name to its length, replaces only the Engineer entries, and slices the final two characters with x[-2:]. + +**Why not certain:** The snippets cover column assignment and the use of .map(). However, they do not explain string slicing syntax (like [-2:]) or list comprehensions with if/else logic, both of which are required to correctly identify option 'a' as the answer. + +**Gap summary:** The current snippets lack coverage for Python's negative string slicing and conditional list comprehensions within a Pandas context. + +**Missing concepts:** negative string slicing (e.g., [-2:] for suffixes); list comprehensions with if-else logic; lambda functions in .map() +**Suggested fix:** Add a snippet or piece that demonstrates string slicing for character extraction and a conditional list comprehension used for data cleaning/replacement. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet explicitly mentions the .map() method being used to apply a function to a Series, which is fundamental to Operations 1 and 3 in the question. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet explicitly mentions the .map() method being used to apply a function to a Series, which is fundamental to Operations 1 and 3 in the question. +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + Why: Demonstrates how to create and assign a new column to a DataFrame (df['C'] = ...), which is used in all operations of the question. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q20 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `20` +- Topic: 7-pandas - lambda - 2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +What will be printed by the following code? + +**Options** +- `a`: Product Units Price +2 C 200 15 +0 A 100 10 +3 D 72 13 +1 B 45 19 +- `b`: Product Units Price +1 B 50 19 +0 A 100 10 +3 D 80 13 +2 C 200 15 +- `c`: Product Units Price +2 C 200 15 +0 A 100 10 +3 D 80 13 +1 B 50 19 +- `d`: Product Units Price +2 C 200 15 +3 D 80 13 +0 A 100 10 +1 B 50 19 + +**Correct answer:** `c` + +**Official explanation:** UnitsCorrected and Revenue are used only for sorting; df1 keeps the original Units and Price columns, and sorting by descending revenue gives rows C, A, D, B. + +**Why not certain:** While .map() and column creation are covered, there is a total absence of information regarding 'sort_values()', the 'ascending=False' parameter, or the 'value if condition else other' ternary syntax used in the lambda. A student would have to guess that 'ascending=False' means descending order to reach the correct answer 'c'. + +**Gap summary:** Crucial sorting operations and conditional logic within lambdas are not explained in the current snippets. + +**Missing concepts:** sort_values(); ascending=False; conditional expressions (if-else ternary) in lambdas; selecting multiple columns via a list of names +**Suggested fix:** Add a snippet or key point covering DataFrame sorting (including direction) and the syntax for conditional logic within anonymous functions. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: Directly explains that the .map() method is used to apply a function to elements of a Series, which is essential for understanding the UnitsCorrected calculation. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: Directly explains that the .map() method is used to apply a function to elements of a Series, which is essential for understanding the UnitsCorrected calculation. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Demonstrates the creation of a new column (C) from existing columns (A and B), mirroring how 'Revenue' is created from 'UnitsCorrected' and 'Price'. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] +- `aiq-1`: Generators and Iterators [w6-generators-and-iterators] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q23 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `23` +- Topic: 9_OOP_Function_3 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following definition of a class called Pack. + +You want to add to this class a method called fitting() that calculates how many times another object of the class Pack would fit inside this object. +The method should return the number of times these other objects would fit completely in this object, and the final value. +The final value is the sum of all values of all objects that fit in it, plus the value of the carrying object self. + +For example, if we execute the lines of code: +backpack = Pack(size=15, value=20) +book = Pack(size=4, value=10) +backpack.fitting(book) + +the output should be: +Amount: 3. Value: 50. + +Which of the following code segments should you place on the missing lines in the class definition to achieve what you want? + +**Options** +- `a`: def fitting(self, other): + if self.size > other.size: + self.total = (self.size // other.size) * other.value + self.value + return f'Amount: {self.size // other.size}. Value: {self.total}.' + else: + return f'Amount: 0. Value: {self.value}.' +- `b`: def fitting(self, other): + if self.size > other.size: + return f'Amount: {self.size // other.size}. Value: {other.value * other.size}.' + else: + return f'Amount: 0. Value: {self.value}.' +- `c`: def fitting(self, other): + self.amount = self.size / other.size + self.total = self.amount * other.value + return f'Amount: {self.amount}. Value: {self.total}.' +- `d`: def fitting(self, other): + self.amount = self.size / other.size + self.total = self.amount * other.value + return 'Amount: {}. Value: {}.'.format(self.amount, self.value if self.size > other.size else self.total) + +**Correct answer:** `a` + +**Official explanation:** Option A uses integer floor division to count only full fits, adds the carried items' value plus self.value, and returns zero items with self.value when the other object does not fit. + +**Why not certain:** The snippets cover class method structure and string formatting, but they do not explain the difference between floor division (//) and float division (/), which is the primary technical distinciton between the correct answer and the distractors. + +**Gap summary:** The student can infer the class structure and string output, but lacks the specific knowledge that // is required for 'fitting completely' (integer division). + +**Missing concepts:** floor division operator (//) vs float division (/) +**Suggested fix:** Add a snippet explaining basic Python arithmetic operators, specifically contrasting / and //. + +**Best snippet** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This piece describes a method ('compare') that compares one object ('self') to another object of the same class, which is the exact architectural pattern required for the 'fitting' method. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This piece describes a method ('compare') that compares one object ('self') to another object of the same class, which is the exact architectural pattern required for the 'fitting' method. +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Shows string formatting patterns for injecting variables into descriptive text, helping the student understand the return statements in the options. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides the foundational syntax for defining classes and attributes, making it clear what 'self.size' and 'self.value' represent. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### introduction-to-python-trial-final-exam-solutions-py22-q24 + +- Exam: `introduction-to-python-trial-final-exam-solutions-py22` +- Question number: `24` +- Topic: 9_OOP_Hard_1 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following definition for a class called Piece. + +And the creation of three objects with the help of the class definition: +a = Piece(diagonal=True, straight=False, initial_position=(0, 0)) +b = Piece(diagonal=False, straight=True, initial_position=(4, 3)) +c = Piece(diagonal=True, straight=True, initial_position=(9, 6)) + +If we run the following statements: +print(a.check_move((4, 4))) +print(b.check_move((5, 5))) +print(c.check_move((6, 6))) + +This will print 3 Boolean values. Of these values, how many times will this be True? + +**Options** +- `a`: 0 +- `b`: 1 +- `c`: 2 +- `d`: 3 + +**Correct answer:** `b` + +**Official explanation:** The first move fails because the row and column differences are both 4, which is above the allowed maximum of 3. The second fails because a straight-only piece cannot move diagonally. The third succeeds because a piece that can move straight and diagonally may move along the same column within 3 steps, so exactly one result is True. + +**Why not certain:** The snippets cover the general structure of classes, constructors, and return statements. However, the question requires a zero-knowledge student to correctly interpret tuple indexing (e.g., target_position[0]) and the mathematical function abs(). Neither of these are explained in the current candidates, making the coordinate math difficult to trace accurately. + +**Gap summary:** Missing core syntax for coordinate tracing (indexing and absolute values). + +**Missing concepts:** Tuple indexing (using [0] and [1] to access coordinates); The abs() function for calculating absolute differences; Tracing multiple Boolean conditions (and, or, not) in a single statement +**Suggested fix:** Add a foundational snippet explaining how 'tuple' data (like coordinates) is accessed via indices and demonstrating the use of abs() for calculating distances or differences between points. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet explains the fundamental structure of a class, the constructor method (__init__), and how attributes are initialized and stored, which is the first step in understanding the Piece class definition and how the instances (a, b, c) are created. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet explains the fundamental structure of a class, the constructor method (__init__), and how attributes are initialized and stored, which is the first step in understanding the Piece class definition and how the instances (a, b, c) are created. +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides an example of a class method (compare), helping the student understand that objects can have functions (methods) that perform logic using their internal attributes (like check_move does here). +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'Return Behavior' piece explains that functions return values like True or False, and the 'Working With Values' section provides context on Booleans. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `aiq-4`: Comprehensions [w6-comprehensions] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q04 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `4` +- Topic: function defaults and loops +- Status: **partial** +- Confidence: `high` + +**Question** + +Suppose you have the following function, which takes two integers as arguments: + +What will be printed by the following line of code: +print(main(1)) + +**Options** +- `a`: This code produces an error as there is a missing argument when calling main. +- `b`: ['1 * 1 = 1', + '1 * 2 = 2', + '1 * 3 = 3', + '1 * 4 = 4', + '1 * 5 = 5', + '1 * 6 = 6', + '1 * 7 = 7', + '1 * 8 = 8', + '1 * 9 = 9', + '1 * 10 = 10'] +- `c`: The code produces a syntax error because of the line: + table.append(f'{x} * {i} = {x*i}') +- `d`: ['1 * 1 = 1', + '1 * 2 = 2', + '1 * 3 = 3', + '1 * 4 = 4', + '1 * 5 = 5', + '1 * 6 = 6', + '1 * 7 = 7', + '1 * 8 = 8', + '1 * 9 = 9', + '1 * 10 = 10', + '1 * 11 = 11'] + +**Correct answer:** `b` + +**Official explanation:** `main(1)` is valid because `y` has default value `11`. The loop starts at `i = 1` and runs while `i < y`, so it appends the multiplication strings for 1 through 10 and stops before 11. + +**Why not certain:** The core hurdle (default arguments) is well-covered. While f-strings and while-loop boundaries aren't explicitly explained as concepts, their behavior can be inferred from the provided logic and the identical past exam questions. + +**Gap summary:** Missing conceptual coverage for 'while loop' stop boundaries and 'f-string' interpolation. + +**Missing concepts:** while loop stop condition; f-strings +**Suggested fix:** Add a conceptual snippet explaining that 'while i < 11' runs for values 1-10 but stops at 11, and a basic f-string syntax example. + +**Best snippet** +- `exam-midterm_2023-9-w3-arguments`: Arguments [w3-arguments] + Why: The clearest demonstration of default arguments in function definitions, which is the primary concept needed to understand why main(1) works. + +**Top 3 snippets** +- `exam-midterm_2023-9-w3-arguments`: Arguments [w3-arguments] + Why: The clearest demonstration of default arguments in function definitions, which is the primary concept needed to understand why main(1) works. +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Shows a function using a default argument and demonstrates building a list using the .append() method within a loop. + +**Minimal sufficient snippets** +- `exam-midterm_2023-9-w3-arguments`: Arguments [w3-arguments] + Why: Explains how arguments default to a value when omitted in the function call. +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: Covers the mechanics of list construction via the append method. + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Test Resit - Introduction to Python - 22/23-4-w2-loops`: Loops [w2-loops] + Why excluded: Directly matches the question's function, call, and logic explanation regarding the default argument and loop range. +- `exam-Resit 22/23-4-w3-arguments`: Arguments [w3-arguments] + Why excluded: Identical question template covering the same function logic and default argument behavior. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q06 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `6` +- Topic: keyword arguments +- Status: **partial** +- Confidence: `medium` + +**Question** + +You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments. + +For example, if you call the function as: +main(apple=1.99, banana=0.99, orange=1.49) +it should return: +4.47 + +Which of the following functions will return the intended value? + +**Options** +- `a`: def main(**kwargs): + total = 0 + for item, price in kwargs.items(): + total += item + return total +- `b`: def main(**kwargs): + total = 0 + for price in kwargs.values(): + total += price + return total +- `c`: def main(**kwargs): + total = 0 + for item, price in kwargs.keys(): + total += price + return total +- `d`: All functions will return the intended value. + +**Correct answer:** `b` + +**Official explanation:** To sum the numeric keyword-argument values, the function must iterate over `kwargs.values()`. Option A adds the string keys instead of the prices, and Option C incorrectly tries to unpack `kwargs.keys()`. + +**Why not certain:** The snippets confirm that `**kwargs` is the correct syntax for 'flexible keyword arguments'. However, they do not explicitly explain dictionary methods like `.values()`, `.items()`, or `.keys()`, which are required to distinguish between options A, B, and C without prior Python knowledge. + +**Gap summary:** Missing an explanation of how to iterate over the values of a `**kwargs` dictionary vs its keys or items. + +**Missing concepts:** kwargs.values(); kwargs.items(); kwargs.keys(); Dictionary iteration methods +**Suggested fix:** Add a snippet explaining that `**kwargs` creates a dictionary and showing how to use `.values()` to access the numeric values passed as arguments. + +**Best snippet** +- `exam-midterm_2023-10-w3-arguments`: Arguments [w3-arguments] + Why: Directly demonstrates the `**kwargs` syntax for capturing a 'flexible number of keyword arguments', which is the first step in identifying the correct function signature. + +**Top 3 snippets** +- `exam-midterm_2023-10-w3-arguments`: Arguments [w3-arguments] + Why: Directly demonstrates the `**kwargs` syntax for capturing a 'flexible number of keyword arguments', which is the first step in identifying the correct function signature. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The first piece reinforces `**kwargs` usage for keyword arguments and mentions dictionaries, which helps a student infer that `kwargs` can be manipulated like a dictionary. + +**Minimal sufficient snippets** +- `exam-midterm_2023-10-w3-arguments`: Arguments [w3-arguments] +- `aiq-4`: Comprehensions [w6-comprehensions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why excluded: Exact match for the question regarding a main function summing keyword arguments. +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why excluded: Identical question structure, function name, and example values. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q15 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `15` +- Topic: Multiple choice +- Status: **partial** +- Confidence: `medium` + +**Question** + +A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the "@" symbol and a domain name, which comes after the "@" symbol. + +You need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments. + +For example, if you execute the following command: +print(main('example@example.com', 'student@uva.nl', 'email@address.com')) + +the output should be: + local domain +0 example example.com +1 student uva.nl +2 email address.com + +Which of the following code segments will return this dataframe as intended? + +You may assume that pandas is already imported as pd. + +**Options** +- `a`: def main(*args): + local = [] + domain = [] + for email in args: + local.append(email.split("@")[0]) + domain.append(email.split("@")[1]) + return pd.DataFrame({local: domain for local, domain in zip(local, domain)}) +- `b`: def main(*args): + data = {} + for email in args: + data['local'] = email.split("@")[0] + data['domain'] = email.split("@")[1] + return pd.DataFrame(data) +- `c`: def main(args): + return pd.DataFrame({ + 'local': [email.split("@")[1] for email in args], + 'data': [email.split("@")[0] for email in args]}) +- `d`: def main(*args): + data = {} + data['local'] = pd.Series([email.split("@")[0] for email in args]) + data['domain'] = pd.Series([email.split("@")[1] for email in args]) + return pd.DataFrame(data) + +**Correct answer:** `d` + +**Official explanation:** Option D constructs one aligned series for the local parts and one for the domains, then returns them in a DataFrame with the correct column names. The other options either overwrite values, build the wrong structure, or use the wrong field names. + +**Why not certain:** The snippets provide the necessary pieces to understand the function signature (*args) and the string manipulation (split). However, they lack an example of list comprehensions and the specific pandas constructor 'pd.DataFrame(dict_of_lists)', which makes it difficult to definitively rule out Option B (which incorrectly overwrites dict values) without prior knowledge. + +**Gap summary:** While the fundamental building blocks (args, splitting, pandas context) are present, the complex construction of a DataFrame from list comprehensions is not represented. + +**Missing concepts:** List comprehensions; Constructing a pandas DataFrame from a dictionary of lists or Series +**Suggested fix:** Add a snippet demonstrating basic list comprehension syntax and the standard way to create a DataFrame from a dictionary: pd.DataFrame({'col': [val1, val2]}). + +**Best snippet** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: This snippet explicitly teaches the syntax and concept of a function accepting a 'flexible number of arguments' (*args), which is the core requirement for the main() function signature in the question. + +**Top 3 snippets** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] + Why: This snippet explicitly teaches the syntax and concept of a function accepting a 'flexible number of arguments' (*args), which is the core requirement for the main() function signature in the question. +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Demonstrates string extraction logic (getting a TLD from a URL), which is conceptually identical to splitting an email address to get the local and domain parts as required by the question. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Confirms the existence and usage of 'pd.Series', helping a student identify why Option D (which uses pd.Series) is a plausible pandas-idiomatic choice. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-6-w3-arguments`: Arguments [w3-arguments] +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q23 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `23` +- Topic: pandas above average salary +- Status: **partial** +- Confidence: `medium` + +**Question** + +Consider the following pandas DataFrame called df: + + Name Age Salary +0 John 25 50000 +1 Jane 30 65000 +2 Alex 35 80000 +3 Lisa 40 70000 +4 Mark 28 55000 + +You need to perform a series of operations on this DataFrame: +- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False. +- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary. +- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary. + +That is, the final result printed should be: + Name Age Salary Above_average Salary_difference +1 Jane 30 65000 True 1000 +2 Alex 35 80000 True 16000 +3 Lisa 40 70000 True 6000 + +Which of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd. + +**Options** +- `a`: mean_salary = round(df['Salary'].mean()) +df['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']]) +df['Salary_difference'] = df['Salary'] - mean_salary +print(df[df['Above_average']==True]) +- `b`: None of the blocks of code will work as intended. +- `c`: Both blocks of code will work as intended. +- `d`: mean_salary = round(df['Salary'].mean()) +df['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False) +df['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary) +print(df[df['Salary_difference']>0]) + +**Correct answer:** `a` + +**Official explanation:** Option A correctly computes the mean salary, builds both required columns, and prints the full DataFrame filtered to rows where Above_average is True. Option D does not print the result in the required way because it filters only on Salary_difference > 0 rather than explicitly using the Above_average column requested in the specification. + +**Why not certain:** While the logic for mean calculation, column creation, and filtering is present, the specific use of list comprehension to build a Series (Option A) or .map(lambda) (Option D) is not explicitly demonstrated in a Pandas context. + +**Gap summary:** There is no snippet demonstrating how to use conditional logic (like list comprehension or lambda functions) to populate a new Pandas column. + +**Missing concepts:** Conditional column creation with list comprehension in Pandas; Using .map(lambda...) for element-wise Series transformation +**Suggested fix:** Add a snippet showing: df['Is_Above'] = [True if x > threshold else False for x in df['Col']]. + +**Best snippet** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Directly addresses calculating values in a Series relative to the mean, which is the core logic for Operation 2 and 3. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Directly addresses calculating values in a Series relative to the mean, which is the core logic for Operation 2 and 3. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows the fundamental syntax for creating a new column in an existing DataFrame by assignment. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Explains boolean masking/filtering in Pandas, which is necessary to identify rows matching the criteria in Operation 3. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023-q24 + +- Exam: `resit-exam-guidelines-for-intro-to-python-6013b0470y-july-2023` +- Question number: `24` +- Topic: pandas lambda output +- Status: **partial** +- Confidence: `medium` + +**Question** + +What will be the output of the following lines of code? + +import pandas as pd + +df = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}) +df['C'] = df['A'].map(lambda x: x + df['B'].sum()) + +print(df) + +**Options** +- `a`: A B C +0 1 4 18 +1 2 5 21 +2 3 6 24 +- `b`: A B C +0 1 4 12 +1 2 5 15 +2 3 6 18 +- `c`: A B C +0 1 4 9 +1 2 5 12 +2 3 6 15 +- `d`: A B C +0 1 4 16 +1 2 5 17 +2 3 6 18 + +**Correct answer:** `d` + +**Official explanation:** df['B'].sum() is 15, so the lambda adds 15 to each value in column A, producing C values 16, 17, and 18. + +**Why not certain:** The snippets explain that .map() applies a function and how to create new columns. However, there is no explicit explanation of 'lambda x:' syntax or the '.sum()' method behavior within a map context, which are critical for calculating the exact values. + +**Gap summary:** The student lacks documentation on lambda functions and the pandas .sum() method. + +**Missing concepts:** lambda functions; pandas .sum() method; scope of variables inside map functions +**Suggested fix:** Add a snippet explaining lambda functions as anonymous functions and another showing common pandas aggregation methods like .sum(). + +**Best snippet** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet explicitly mentions that the .map() method allows applying a function, which is the core mechanism used in the question to transform column 'A'. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] + Why: This snippet explicitly mentions that the .map() method allows applying a function, which is the core mechanism used in the question to transform column 'A'. +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Helps the student understand the context of creating a new column 'C' from existing columns 'A' and 'B' in a pandas DataFrame. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Provides an example of a more complex transformation on a Series (like a column) involving a mean calculation, similar to the sum() used here. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals`: Working With Values [w5-working-with-values] +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q09 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `9` +- Topic: Dictionaries and Mappings +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have a dictionary that represents the scores of students in a math competition: +math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82} + +You want to find and print the names of the students who scored above the average score. + +Which of the following code segments will work as intended? + +**Options** +- `a`: average_score = sum(math_scores.values()) / len(math_scores) +for student in math_scores.keys(): + if math_scores[student] > average_score: + print(student) +- `b`: for student in math_scores: + if math_scores[student] > (sum(math_scores.values()) / len(math_scores)): + print(student) +- `c`: Both code segments will work as intended. +- `d`: None of the code segments will work as intended. + +**Correct answer:** `c` + +**Official explanation:** Both snippets correctly print the names whose scores are above the average. A computes the average once, while B recomputes it inside the loop but still produces the correct result. + +**Why not certain:** If the near-identical piece is excluded, the remaining snippets describe similar problems but do not explicitly show the syntax for 'sum(dict.values())' or 'len(dict)'. A student might guess based on the problem descriptions, but the technical logic for why both 'math_scores.keys()' and 'math_scores' work as iterators is missing. + +**Gap summary:** Existing snippets are mostly question prompts without the actual code solutions, making it hard to learn syntax. + +**Missing concepts:** sum() and len() applied to dictionary values; Equivalence of iterating over a dictionary directly vs. its .keys() method; Dictionary filtering syntax +**Suggested fix:** Add a conceptual snippet explaining common dictionary methods like .keys(), .values(), and how to calculate statistics like averages from them. + +**Best snippet** +- `exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: While it lacks the solution code, it presents a near-identical problem structure (employee ratings vs student scores) and the goal of filtering a dictionary by value. + +**Top 3 snippets** +- `exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: While it lacks the solution code, it presents a near-identical problem structure (employee ratings vs student scores) and the goal of filtering a dictionary by value. +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Introduces the concept of calculating an 'average' from dictionary data, which is central to the question. +- `exam-extra_practice-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why: Shows a relationship between a list of items and a dictionary of counts/values, helping understand how dictionaries track attributes. + +**Minimal sufficient snippets** +- `exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] +- `exam-extra_practice-5-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-extra_practice-4-w2-dictionaries-and-mappings`: Dictionaries and Mappings [w2-dictionaries-and-mappings] + Why excluded: Matches the exact question text, the student score dictionary, and the goal of finding names above the average. + +### resit-solutions-for-introduction-to-python-35761538-q15 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `15` +- Topic: string - operations - 3 +- Status: **partial** +- Confidence: `medium` + +**Question** + +A company wants to extract the components of email addresses. An email address consists of the local part, which comes before the "@" symbol and a domain name, which comes after the "@" symbol. + +You need to create a function called main() which accepts a flexible number of strings representing email addresses and returns a DataFrame. Your DataFrame should have a column called 'local' which contains the local parts and a column called 'domain' which contains the domain names of the email addresses that were passed as arguments. + +For example, if you execute the following command: +print(main('example@example.com', 'student@uva.nl', 'email@address.com')) + +the output should be: + local domain +0 example example.com +1 student uva.nl +2 email address.com + +Which of the following code segments will return this dataframe as intended? + +You may assume that pandas is already imported as pd. + +**Options** +- `a`: def main(*args): + data = {} + data['local'] = pd.Series([email.split("@")[0] for email in args]) + data['domain'] = pd.Series([email.split("@")[1] for email in args]) + return pd.DataFrame(data) +- `b`: def main(args): + return pd.DataFrame({ + 'local': [email.split("@")[1] for email in args], + 'data': [email.split("@")[0] for email in args]}) +- `c`: def main(*args): + data = {} + for email in args: + data['local'] = email.split("@")[0] + data['domain'] = email.split("@")[1] + return pd.DataFrame(data) +- `d`: def main(*args): + local = [] + domain = [] + for email in args: + local.append(email.split("@")[0]) + domain.append(email.split("@")[1]) + return pd.DataFrame({local: domain for local, domain in zip(local, domain)}) + +**Correct answer:** `a` + +**Official explanation:** Option A builds aligned pandas Series for the local parts and domains, then returns them in a DataFrame with the correct column names. The other options either swap fields, overwrite values, or construct the DataFrame incorrectly. + +**Why not certain:** The snippets cover the flexible arguments (*args) and the looping mechanics, and provide context for pandas Series. However, the specific syntax for constructing a DataFrame from a dictionary of Series is not explicitly demonstrated, nor is the use of '.split()' on strings for character-based extraction. + +**Gap summary:** The student would know how to handle multiple arguments and loops, but might struggle with the specific string extraction (.split) and DataFrame assembly syntax. + +**Missing concepts:** string.split() method; pd.DataFrame(dictionary) construction; List comprehension for Series creation +**Suggested fix:** Add a snippet or detail piece showing how to create a DataFrame from a dictionary of lists or Series, and another showing string splitting. + +**Best snippet** +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: This snippet directly addresses the requirement for a function that accepts a 'flexible number of arguments' (*args), which is a key differentiator between the correct and incorrect options. + +**Top 3 snippets** +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: This snippet directly addresses the requirement for a function that accepts a 'flexible number of arguments' (*args), which is a key differentiator between the correct and incorrect options. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: Shows the implementation syntax for iterating over *args ('for num in args'), which is necessary for extracting data from each email string. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Provides context for pandas Series, which are explicitly used in the correct option (Option A) to build the DataFrame. + +**Minimal sufficient snippets** +- `exam-extra_practice-9-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: Covers the *args requirement. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: Provides the loop syntax for flexible arguments. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Validates the use of pd.Series. +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: Provides a conceptual parallel for extracting parts of a string (TLD from URL) even if the delimiter differs. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q16 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `16` +- Topic: 6_OOP_Easy_1 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following definition of a class called Employee: + +class Employee: + def __init__(self, name, role, gender = 'not specified'): + self.name = name + self.role = role + self.gender = gender + +What will be the output if we execute the following lines of code? + +employee1 = Employee('John Smith', 'HR representative') +print(employee1.name == 'John Smith') +print(employee1.gender == 'not specified') + +**Options** +- `a`: True +True +- `b`: True +False +- `c`: False +True +- `d`: False +False + +**Correct answer:** `a` + +**Official explanation:** The name comparison is true because the object stores 'John Smith', and the gender comparison is also true because the default value 'not specified' is used when no gender is provided. + +**Why not certain:** The snippets explain default arguments and show that comparisons result in True/False. However, there is no direct example showing 'self.attribute = parameter' being accessed later via 'object.attribute', though it is somewhat inferable from the OOP Fundamentals piece. + +**Gap summary:** Missing a concrete code example of attribute assignment and retrieval in a class. + +**Missing concepts:** Explicit syntax for attribute access (obj.attr); Mapping of __init__ arguments to self-assigned attributes +**Suggested fix:** Add a snippet showing a simple class 'Person' where 'self.name = name' is followed by a 'print(p1.name == ...)' example. + +**Best snippet** +- `exam-Resit 22/23-4-w3-arguments`: Arguments [w3-arguments] + Why: This snippet is the most relevant because it explicitly explains how default arguments work (e.g., 'y defaults to 11' when omitted), which is the key 'trick' for the gender attribute in this question. + +**Top 3 snippets** +- `exam-Resit 22/23-4-w3-arguments`: Arguments [w3-arguments] + Why: This snippet is the most relevant because it explicitly explains how default arguments work (e.g., 'y defaults to 11' when omitted), which is the key 'trick' for the gender attribute in this question. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides the conceptual framework for defining classes and initializing attributes (name, mode) during object construction. +- `exam-Resit 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Demonstrates that comparison operations (==) in Python print 'True' or 'False', helping a zero-knowledge student understand the output format. + +**Minimal sufficient snippets** +- `exam-Resit 22/23-4-w3-arguments`: Arguments [w3-arguments] +- `exam-Resit 22/23-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q17 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `17` +- Topic: 8_Datetime_Easy_2 +- Status: **partial** +- Confidence: `medium` + +**Question** + +Which other code fragment will print the same output as the following? + +from datetime import datetime, timedelta +print((datetime.strptime('2023/1/10', '%Y/%m/%d') - datetime(2023, 1, 1)).days + 1) + +**Options** +- `a`: from datetime import datetime, timedelta +print(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days) +- `b`: from datetime import datetime, timedelta +print(timedelta(datetime(2023, 1, 10) - datetime(2023, 1, 1)).days + 1) +- `c`: from datetime import datetime, timedelta +print((datetime(2023, 1, 10) - datetime.strptime('2023-1-1', '%Y-%m-%d')).days) +- `d`: from datetime import datetime, timedelta +print((datetime(2023, 1, 11) - datetime(2023, 1, 1)).days) + +**Correct answer:** `d` + +**Official explanation:** The original code computes the difference in days between January 10 and January 1, then adds 1, yielding 10. Option D also yields 10 by subtracting January 1 from January 11. + +**Why not certain:** The best snippet covers the subtraction logic and attribute access perfectly. However, there is no explanation for datetime.strptime() or the standard datetime(Y, M, D) constructor. A student would have to infer that '2023/1/10' in strptime is equivalent to datetime(2023, 1, 10), which is a reasonable but unverified leap for a total beginner. + +**Gap summary:** Lack of documentation for datetime object creation methods (constructor vs parsing). + +**Missing concepts:** datetime.strptime(); datetime(year, month, day) constructor +**Suggested fix:** Add an AI example or key point showing that datetime objects can be created via numeric arguments or by parsing strings with strptime. + +**Best snippet** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: This piece explains the exact mechanics required: that subtracting two datetime objects results in a timedelta, that .days converts it to an integer, and it even mentions the '+ 1' logic for inclusive counting. + +**Top 3 snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + Why: This piece explains the exact mechanics required: that subtracting two datetime objects results in a timedelta, that .days converts it to an integer, and it even mentions the '+ 1' logic for inclusive counting. +- `kp-8`: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns [w6-comprehensions] + Why: Contains key point kp-8 which acknowledges the 'Which code fragment prints the SAME output as...?' question pattern frequently seen in exams. + +**Minimal sufficient snippets** +- `exam-intro_python_sample_final_24_25-10-w6-datetime`: Datetime [w6-datetime] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q19 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `19` +- Topic: 6_OOP_Function_1 +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following definition for a class called Animals: + +class Animals: + def __init__(self, name, sound, legs=None, fin=None): + self.name = name + self.sound = sound + self.legs = legs + self.fin = fin + + # missing lines + # ... + +You need to add two methods to the class: +1. The walk() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'legs'. If the Animal object does not, return 'Cannot walk!'. +2. The swim() method, which returns the 'sound' attribute an Animal object has if the Animal object has 'fin'. If the Animal object does not, return 'Cannot swim!'. + +For example, if we execute the following commands: +cat = Animals('kitty', legs=True, sound='Meow!') +fish = Animals('nemo', fin=True, sound='Blob!') +print(cat.walk()) +print(cat.swim()) +print(fish.swim()) +print(fish.walk()) + +the output should be: +Meow! +Cannot swim! +Blob! +Cannot walk! + +Which of the following code segments should you place on the missing lines in the class definition to achieve what you want? + +**Options** +- `a`: def walk(self): + return self.sound if self.legs else 'Cannot walk!' +def swim(self): + return self.sound if self.fin else 'Cannot swim!' +- `b`: def walk(self): + if self.legs == True: + return self.sound + else: + return 'Cannot walk!' +def swim(self): + if self.fin == True: + return self.sound + else: + return 'Cannot swim!' +- `c`: Both code segments will work as intended. +- `d`: Neither code segment will work as intended. + +**Correct answer:** `c` + +**Official explanation:** Both shown method implementations use the instance attributes to return the animal's sound when the relevant boolean attribute is present and the required fallback message otherwise. + +**Why not certain:** The snippets cover class structure, method definitions, and basic if/else logic (Option 'b'). However, there is no explanation of the 'ternary operator' (x if condition else y) used in Option 'a'. Without knowing this syntax, a student cannot confidently select 'c' (Both work). + +**Gap summary:** The main gap is the lack of documentation for the one-line ternary if-else operator syntax used in option 'a'. + +**Missing concepts:** ternary conditional operator (x if condition else y) +**Suggested fix:** Add an AI-generated snippet or a common question item that explains the 'Inline If-Else' or 'Ternary Operator' syntax. + +**Best snippet** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet explicitly describes adding a method ('compare') to an existing class that uses instance attributes to return a result based on conditional logic, which mirrors the task of adding the 'walk' and 'swim' methods. + +**Top 3 snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: This snippet explicitly describes adding a method ('compare') to an existing class that uses instance attributes to return a result based on conditional logic, which mirrors the task of adding the 'walk' and 'swim' methods. +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + Why: Provides the foundational context for defining a class with multiple attributes and how they are initialized in the constructor (__init__), helping the student understand 'self.legs' and 'self.fin'. +- `exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names`: Objects and Names [w1-objects-and-names] + Why: Demonstrates basic if/else control flow for decision-making, which is the core logic required for option 'b'. + +**Minimal sufficient snippets** +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals`: OOP Fundamentals [w4-oop-fundamentals] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### resit-solutions-for-introduction-to-python-35761538-q23 + +- Exam: `resit-solutions-for-introduction-to-python-35761538` +- Question number: `23` +- Topic: pandas - hard - 3 +- Status: **partial** +- Confidence: `medium` + +**Question** + +Consider the following pandas DataFrame called df: + + Name Age Salary +0 John 25 50000 +1 Jane 30 65000 +2 Alex 35 80000 +3 Lisa 40 70000 +4 Mark 28 55000 + +You need to perform a series of operations on this DataFrame. +- Operation 1: Create a new column called Above_average, which contains True if the employee's salary is above the average salary of all the employees, otherwise False. +- Operation 2: Create a new column called Salary_difference, which represents how much higher an employee's salary is than the average salary. +- Operation 3: Print the segment of the adapted DataFrame that contains all the columns, but only the rows in which the employees earn more than the average salary. + +That is, the final result printed should be: + Name Age Salary Above_average Salary_difference +1 Jane 30 65000 True 100 +2 Alex 35 80000 True 16000 +3 Lisa 40 70000 True 6000 + +Which of the following blocks of code will perform these operations as intended? You may assume the pandas module is already imported as pd. + +**Options** +- `a`: mean_salary = round(df['Salary'].mean()) +df['Above_average'] = pd.Series([True if salary > mean_salary else False for salary in df['Salary']]) +df['Salary_difference'] = df['Salary'] - mean_salary +print(df[df['Above_average']==True]) +- `b`: mean_salary = round(df['Salary'].mean()) +df['Above_average'] = df['Salary'].map(lambda x: True if x > mean_salary else False) +df['Salary_difference'] = df['Salary'].map(lambda x: x - mean_salary) +print(df[df['Salary_difference']>0]) +- `c`: Both blocks of code will work as intended. +- `d`: None of the blocks of code will work as intended. + +**Correct answer:** `c` + +**Official explanation:** Both code blocks compute the rounded mean salary, derive an above-average indicator, compute salary differences from that mean, and filter the rows with positive differences. + +**Why not certain:** The snippets cover column creation and vectorized math. However, the use of '.mean()' as a method on a column, the '.map()' method, and 'lambda' functions are entirely missing. A student without prior knowledge would struggle to verify if '.map(lambda x: ...)' is valid syntax or how '.mean()' works. + +**Gap summary:** Crucial Pandas methods (map, mean) and Python functional features (lambda) are not demonstrated in any selectable snippet. + +**Missing concepts:** Series.mean(); Series.map(); lambda functions in pandas context +**Suggested fix:** Add a snippet demonstrating how to calculate a column mean and use .map(lambda x: ...) to create conditional columns. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows how to create a new column (C) from existing columns (A and B) using vectorized operations, which directly relates to creating 'Salary_difference' and assigning new columns in the question. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Shows how to create a new column (C) from existing columns (A and B) using vectorized operations, which directly relates to creating 'Salary_difference' and assigning new columns in the question. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Mentions using a boolean mask on the index or columns for filtering rows, which is necessary for understanding the print(df[df[...]]) operations in the options. +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Describes the concept of creating a new Series based on the difference between elements and their mean, supporting the logic in Operation 2. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures`: Pandas Core Structures [w5-pandas-core-structures] + Why: Teaches column creation and vectorization. +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: Provides a hint towards boolean filtering syntax. + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### sample-final-plus-answers-q04 + +- Exam: `sample-final-plus-answers` +- Question number: `4` +- Topic: phone number formatting +- Status: **partial** +- Confidence: `medium` + +**Question** + +You need to write a function called format_phone_number that formats phone numbers. +The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the "-" character) at various places. +For example, the following function calls: +format_phone_number("020-525-1400") +format_phone_number("020-5251400") +format_phone_number("020-525-14-00") +should all return the string: +"0205251400" +Which of the following code segments does not achieve what you want? + +**Options** +- `a`: def format_phone_number(number): + number.replace("-", "") + return number +- `b`: def format_phone_number(number): + return number.replace("-", "") +- `c`: def format_phone_number(number): + digits = [] + for char in number: + if char in "0123456789": + digits.append(char) + return "".join(digits) +- `d`: def format_phone_number(number): + return "".join(number.split("-")) + +**Correct answer:** `a` + +**Official explanation:** Option A calls `replace` but does not store its result, so it returns the original unchanged string. The other options all build and return the digits without the dashes. + +**Why not certain:** While the conceptual snippets explain mutation vs. rebinding, there is no snippet in the candidate list (other than the identical exam question) that explains the specific behavior of string methods like .replace(), .split(), or .join(). A student with zero knowledge would not know what these methods do. + +**Gap summary:** The snippets explain general name-binding concepts but lack specific documentation on string methods and string immutability. + +**Missing concepts:** String immutability (strings cannot be changed in place); Behavior of str.replace() (returns a NEW string); Behavior of str.split() and str.join() for string cleanup +**Suggested fix:** Add a summary snippet covering core string operations (replace, split, join, strip) and explicitly stating that strings are immutable in Python. + +**Best snippet** +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: The 'Objects and Names' piece explains the difference between rebinding a name and mutating an object. This is critical for understanding why Option A fails: `number.replace` creates a new string object but the code fails to rebind the name `number` to that new object. + +**Top 3 snippets** +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] + Why: The 'Objects and Names' piece explains the difference between rebinding a name and mutating an object. This is critical for understanding why Option A fails: `number.replace` creates a new string object but the code fails to rebind the name `number` to that new object. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'Return Behavior' and 'Objects and Names' pieces emphasize tracing returned values and how functions handle assignments, which helps identify that the ignored return value in Option A is the root cause. + +**Minimal sufficient snippets** +- `aiq-5`: Inspecting and Selecting Data [w5-inspecting-and-selecting-data] +- `aiq-4`: Comprehensions [w6-comprehensions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why excluded: This piece contains the exact question text and context provided in the question JSON. + +### sample-final-plus-answers-q09 + +- Exam: `sample-final-plus-answers` +- Question number: `9` +- Topic: Datetime parsing +- Status: **partial** +- Confidence: `medium` + +**Question** + +Take a look at the following code segment. + +Suppose that you call the function like this: +get_months(["03/02/2013", "03.02.2013", "03-02-2013"]) + +What does the function call return? + +**Options** +- `a`: [3, None, 2] +- `b`: [2, None, 3] +- `c`: [3, 2] +- `d`: [2, 3] + +**Correct answer:** `a` + +**Official explanation:** The first string contains `/`, so it is parsed as month/day/year and gives month 3. The second string contains neither `-` nor `/`, so it becomes `None`. The third contains `-`, so it is parsed as day-month-year and gives month 2. + +**Why not certain:** The identical past exam piece provides the answer directly. If excluded, there are no general snippets explaining Datetime format codes (%d, %m, %Y). While a student might guess that 'm' stands for month and 'd' for day, they would lack confirmation without a specific datetime reference. + +**Gap summary:** There is no general reference for the datetime module, specifically for strptime and its format codes. + +**Missing concepts:** datetime.strptime() function purpose; Datetime format codes: %d (day), %m (month), %Y (4-digit year); Datetime object attributes: .month +**Suggested fix:** Add a general-purpose 'Datetime Basics' snippet. + +**Best snippet** +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: While not about datetime, it provides a parallel logic example where a function processes a string input containing specific characters ('-') to determine formatting, which helps a student understand conditional string processing. + +**Top 3 snippets** +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] + Why: While not about datetime, it provides a parallel logic example where a function processes a string input containing specific characters ('-') to determine formatting, which helps a student understand conditional string processing. +- `exam-trial_midterm-6-w2-conditions`: Conditions [w2-conditions] + Why: Demonstrates the structural pattern of iterating through a list and conditionally appending results to a new list, which is the core structure of the get_months function. + +**Minimal sufficient snippets** +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions`: Defining and Calling Functions [w3-defining-and-calling-functions] +- `exam-trial_midterm-6-w2-conditions`: Conditions [w2-conditions] + +**Near-identical past-exam pieces excluded from ranking** +- `exam-intro_python_sample_final_24_25-9-w6-datetime`: Datetime [w6-datetime] + Why excluded: This is the exact same question, providing the code, the call, and an explanation of why each string is parsed differently. + +### sample-final-plus-answers-q17 + +- Exam: `sample-final-plus-answers` +- Question number: `17` +- Topic: Empty-sequence equality chain +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following function called main: +def main(x): + y = [] + for i in x: + if len(i) == 0: + y.append(True) + else: + y.append(False) + return y[0] == y[1] == y[2] + +What will be printed by the following lines: +print(main([{}, {}, {}])) +print(main([[1], [2, 2], [3, 3, 3]])) +print(main([[1], [2], [3]])) + +**Options** +- `a`: True +False +False +- `b`: False +False +True +- `c`: True +False +True +- `d`: True +True +True + +**Correct answer:** `d` + +**Official explanation:** The first call builds [True, True, True], the second call builds [False, False, False], and the third call also builds [False, False, False]. In all three cases the chained equality compares three identical booleans, so each printed result is True. + +**Why not certain:** While the structural pattern is matched by the best snippet, no snippet explicitly defines the behavior of len() on an empty dictionary {} or an empty list [], nor does it explain Python's chained equality (a == b == c). A student might guess len({}) is 0, but it isn't explicitly provided. + +**Gap summary:** Missing explicit definitions for the len() function on various empty collections and the behavior of chained comparison operators. + +**Missing concepts:** len() results for empty dicts and lists; chained equality (a == b == c) evaluation +**Suggested fix:** Add a piece to a 'Working with Values' or 'Built-in Functions' snippet explaining that len() returns 0 for {}, [], and "", and that a == b == c checks if all three are equal. + +**Best snippet** +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: This snippet uses an identical structural pattern: a function taking a list, iterating through it, checking a condition, and appending results to a new list 'y' before returning. It helps the student map the logic of the question's 'main' function. + +**Top 3 snippets** +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: This snippet uses an identical structural pattern: a function taking a list, iterating through it, checking a condition, and appending results to a new list 'y' before returning. It helps the student map the logic of the question's 'main' function. +- `exam-midterm_2024-1-w3-return-behavior`: Return Behavior [w3-return-behavior] + Why: Helps students understand how boolean variables (True/False) interact within conditions and what results from evaluating logical chains. +- `aiq-4`: Comprehensions [w6-comprehensions] + Why: The 'Lists and Sets' piece provides context on collection equality, which reinforces the concept of comparing sequences. + +**Minimal sufficient snippets** +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] +- `exam-midterm_2024-1-w3-return-behavior`: Return Behavior [w3-return-behavior] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. + +### trial-final-exam-solutions-introduction-to-python-3077951-q17 + +- Exam: `trial-final-exam-solutions-introduction-to-python-3077951` +- Question number: `17` +- Topic: List logic +- Status: **partial** +- Confidence: `medium` + +**Question** + +You have the following function called main: + +def main(x): + y = [] + for i in x: + if len(i) == 0: + y.append(True) + else: + y.append(False) + return y[0] == y[1] == y[2] + +What are the outputs of the following lines: +main([[], (), []]) +main([[1], [2, 2], [3, 3, 3]]) +main([[1], [2], [3]]) + +**Options** +- `a`: True +True +True +- `b`: True +False +True +- `c`: True +False +False +- `d`: False +False +True + +**Correct answer:** `a` + +**Official explanation:** For the first call, each element has length 0, so y becomes [True, True, True] and the comparison is True. In the second and third calls, each element has non-zero length, so y becomes [False, False, False] and the chained equality is also True. + +**Why not certain:** The snippets provide the basic blocks (loops, appends, len, equality). However, a student with zero knowledge might not realize that 'False == False == False' evaluates to True (chained equality) or that empty tuples () and lists [] both have length 0. + +**Gap summary:** Missing explicit explanation of chained equality behavior and the specific length of empty containers (lists/tuples). + +**Missing concepts:** chained equality (a == b == c); length of empty containers ([], ()) +**Suggested fix:** Add a snippet demonstrating that len([]) and len(()) are both 0, and another showing how chained equality works with Boolean values. + +**Best snippet** +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: This snippet mirrors the exact structural pattern of the question: initializing an empty list, looping through an input list, using a conditional to append values, and returning a result derived from the new list. + +**Top 3 snippets** +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] + Why: This snippet mirrors the exact structural pattern of the question: initializing an empty list, looping through an input list, using a conditional to append values, and returning a result derived from the new list. +- `exam-extra_practice-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + Why: Demonstrates the use of the len() function and the equality operator (==) in a return statement, which are key components of the logic in the main question. +- `exam-trial_midterm-6-w2-conditions`: Conditions [w2-conditions] + Why: Provides an additional example of the list-building pattern (loop + append) which reinforces the execution flow of the provided code context. + +**Minimal sufficient snippets** +- `exam-midterm_2024-15-w1-functions-and-imports`: Functions and Imports [w1-functions-and-imports] +- `exam-extra_practice-1-w2-lists-and-sets`: Lists and Sets [w2-lists-and-sets] + +**Near-identical past-exam pieces excluded from ranking** +- None recorded. diff --git a/data/vision_exam_pipeline/review_packets/selectable_snippet_catalog.md b/data/vision_exam_pipeline/review_packets/selectable_snippet_catalog.md new file mode 100644 index 0000000..42b5d89 --- /dev/null +++ b/data/vision_exam_pipeline/review_packets/selectable_snippet_catalog.md @@ -0,0 +1,5912 @@ +# Selectable Snippet Catalog + +Human-readable export of the full selectable snippet snapshot used by the evaluation pipeline. + +## Summary + +- Selectable pieces: **801** +- Snippet families: **395** +- Weeks represented: **1, 2, 3, 4, 5, 6** + +### Piece Counts By Bucket + +- `keyPoints`: 241 +- `aiExamples`: 201 +- `recommended`: 189 +- `aiQuestions`: 86 +- `additional`: 84 + +### Piece Counts By Week + +- Week 1: 153 +- Week 2: 158 +- Week 3: 143 +- Week 4: 132 +- Week 5: 127 +- Week 6: 88 + +## Week 1 + +Snippet families in this group: **90** + +### Built-ins Intro, Functions, and Modules + +- Snippet ID: `subtopic:w1-functions-and-imports:w1-functions-and-imports-core` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `9` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: Import module under its original name import numpy numpy.random.randint(1, 10) # works import numpy as np np.random.randint(1, 10) # works numpy.random.randint(1, 10) # ERROR from numpy.random import randint randint(1,… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: Direct import plus alias binds both names clear_names() import extension as ex try: print(ex.YEAR) except Exception as e: print(e) try: print(extension.YEAR) except Exception as e: print(e) Keep track of which name is a… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: from-import binds only the imported name clear_names() import extension import extension as ex try: print(ex.YEAR) except Exception as e: print(e) try: print(extension.YEAR) except Exception as e: print(e) Keep track of… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: Aliased from-import uses the alias locally clear_names() from extension import create_absolute_year try: print(create_absolute_year(1)) except Exception as e: print(e) try: print(YEAR) except Exception as e: print(e) Ke… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: import module does not create bare globals clear_names() from extension import create_absolute_year as cay try: print(create_absolute_year(1)) except Exception as e: print(e) try: print(cay(1)) except Exception as e: pr… +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: Import module under its original name clear_names() try: print(YEAR) except Exception as e: print(Exception) try: print(extension.YEAR) except Exception as e: print(e) import extension try: print(YEAR) except Exception… +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: Income tax branches and return shape Suppose your country imposes the following tax brackets: Bracket Tax Taxable income rate Over Not over 1 10% $0 $11,000 2 12% $11,000 $45,000 3 22% $45,000 $95,000 4 32% $95,000 If y… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: `import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Built-ins Intro, Functions, and Modules + Preview: Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller. + +### Functions and Imports + +- Snippet ID: `item:cs-23b2cfd4d6` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `cs-23b2cfd4d6` + Bucket: `additional` | Type: `source_notebook` + Preview: imports clear_names() from extension import create_absolute_year as cay try: print(create_absolute_year(1)) except Exception as e: print(e) try: print(cay(1)) except Exception as e: print(e) name 'create_absolute_year'… + +### Functions and Imports + +- Snippet ID: `item:cs-4155022ebf` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `cs-4155022ebf` + Bucket: `additional` | Type: `source_notebook` + Preview: imports clear_names() from extension import create_absolute_year try: print(create_absolute_year(1)) except Exception as e: print(e) try: print(YEAR) except Exception as e: print(e) 2026 name 'YEAR' is not defined + +### Functions and Imports + +- Snippet ID: `item:cs-5b89a10dcd` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `cs-5b89a10dcd` + Bucket: `additional` | Type: `source_notebook` + Preview: imports clear_names() try: print(YEAR) except Exception as e: print(Exception) try: print(extension.YEAR) except Exception as e: print(e) import extension try: print(YEAR) except Exception as e: print(e) try: print(exte… + +### Functions and Imports + +- Snippet ID: `item:cs-6d0d650063` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `cs-6d0d650063` + Bucket: `recommended` | Type: `source_notebook` + Preview: imports clear_names() import extension import extension as ex try: print(ex.YEAR) except Exception as e: print(e) try: print(extension.YEAR) except Exception as e: print(e) 2025 2025 + +### Functions and Imports + +- Snippet ID: `item:cs-beb6591b24` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `cs-beb6591b24` + Bucket: `recommended` | Type: `source_notebook` + Preview: imports clear_names() import extension as ex try: print(ex.YEAR) except Exception as e: print(e) try: print(extension.YEAR) except Exception as e: print(e) 2025 name 'extension' is not defined + +### Functions and Imports + +- Snippet ID: `item:cs-c25503e5db` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `cs-c25503e5db` + Bucket: `additional` | Type: `source_notebook` + Preview: imports %%writefile extension.py # In this cell we create a python file and write that to the hard disk (either of your computer or to the cloud depending where you run your code. # We will import this file to show how… + +### Functions and Imports + +- Snippet ID: `item:exam-Resit 22/23-5-w1-functions-and-imports` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `exam-Resit 22/23-5-w1-functions-and-imports` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have a list called x. Which of the following code segments will print the following list? [5, 4, 3, 2, 1] a b c d c Option A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts… + +### Functions and Imports + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-24-w2-conditions` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-24-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: Which script does NOT print the correct answer for the area of a circle? A B C D C If math is imported as constants, it must be referred to as 'constants.pi'. 'math.pi' will no longer be available unless 'math' was also… + +### Functions and Imports + +- Snippet ID: `item:exam-midterm_2023-12-w1-functions-and-imports` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `exam-midterm_2023-12-w1-functions-and-imports` + Bucket: `recommended` | Type: `source_exam` + Preview: You want to write a program to calculate your income tax for 2023. + +### Functions and Imports + +- Snippet ID: `item:exam-midterm_2024-15-w1-functions-and-imports` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `exam-midterm_2024-15-w1-functions-and-imports` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: def main(lst, condition=lambda x: x): y = [] for x in lst: if condition(x): y.append(x) return y What will this function return, when called in the following way: main([1, 2, 3, 4, 5… + +### Functions and Imports + +- Snippet ID: `item:exam-midterm_2024-16-w1-functions-and-imports` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `exam-midterm_2024-16-w1-functions-and-imports` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather alert system. + +### Functions and Imports + +- Snippet ID: `item:kp-1-d2` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `9` + +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Call | Use | Typical result int('123') | string to integer | 123 float('123') | string to float | 123.0 str(123.0) | number to string | '123.0' round(x, 2) | round for display/checking | 2 decimals +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dict membership checks KEYS, not values d = {1: 4, 2: 3} print(1 in d) # True (1 is a key) print(4 in d) # False (4 is a value, not a key) +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Wrong bracket errors print[1] # TypeError: 'function' object is not subscriptable l1 = [1,2,3] l1(1) # TypeError: 'list' object is not callable +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Mix defined and *args def adder(n1, n2, *args): result = n1 + n2 for number in args: result += number return result print(adder(1, 2, 3, 4, 5)) # 15 +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Tool | Returns | Best for map(f, seq) | lazy transformed iterable | same-length transform filter(f, seq) | lazy filtered iterable | keep matching items sorted(seq, key=...) | new sorted list | comp… +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Form | What it means | Exam use '...'/"..." | basic literals | choose quote style \n / \t | newline / tab | predict printed output r'...' | raw string | slashes stay literal s[i:j:k] | string slici… +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Method | Returns | Trap s.find(x) | index or -1 | never raises s.index(x) | index | raises if missing s.replace(a, b) | new string | strings are immutable sep.join(seq) | new joined string | separa… +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Selector | What it uses | Result df.loc[row, col] | labels | endpoint-inclusive slicing df.iloc[row, col] | positions | Python-style exclusive slice df.head(n) | first rows | quick inspect df[df['A… +- `kp-1-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Operation | Main axis/key idea | When useful pd.concat([...], axis=0) | stack rows | same columns pd.concat([...], axis=1) | add columns | aligned index df.merge(...) | join on key(s) | relational… + +### Functions and Imports + +- Snippet ID: `item:ks-b6a39f66a2` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `ks-b6a39f66a2` + Bucket: `recommended` | Type: `source_lecture` + Preview: intro ### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen
                  • A function is a grouping of code that can perform a certain task a… + +### Functions and Imports + +- Snippet ID: `item:ks-f43422a4cf` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `ks-f43422a4cf` + Bucket: `recommended` | Type: `source_lecture` + Preview: Importing packages Multiple import styles. 'import X' makes X available. 'import X as Y' renames. 'from X import Z' brings Z directly into namespace. 'from X import Z as W' renames. Once you use 'as', the original name… + +### Functions and Imports + +- Snippet ID: `item:manual-implicit-none` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `manual-implicit-none` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What does a function return if it reaches the end without `return`? Python returns `None` if no `return` statement is executed. def f(): print('hi') print(f()) + +### Functions and Imports + +- Snippet ID: `item:manual-import-names` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `manual-import-names` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do different import forms change the names you can use locally? `import math` gives `math.sqrt`, `import math as m` gives `m.sqrt`, and `from math import sqrt` gives `sqrt(...)` directly. import math import math as… + +### Functions and Imports + +- Snippet ID: `item:manual-print-vs-return` +- Topic: Functions and Imports +- Card ID: `w1-functions-and-imports` +- Piece count: `1` + +- `manual-print-vs-return` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What is the difference between printing a value and returning a value from a function? `print(x)` shows a value on screen. `return x` sends a value back to the caller so it can be stored, reused, or printed later. def f… + +### Objects and Names + +- Snippet ID: `item:aiq-1` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `16` + +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types. I is correct (e.g. a=1, b=2, bot… +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What is the result of (a//b)*b + a%b? Arithmetic operators +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Slicing / mutability Track which names point to the same object and which slice creates a copy before the mutation happens. Slicing / mutability +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings. Check whether the method mutates the list in place and what the list looks like after each call. Exam • trial_m… +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Assume you already have a variable a, which is an integer between 1 and 4. Exam • midterm_2023 • Q15 mylist = [1, 3, 5, 7, 9] print(mylist[a] + mylist[-a]) +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Condition flow and branch result Exam • midterm_2024 • Q1 Consider the following code snippet: a = True b = False c = True d = False if not (a or b) and (c or d): print("True") else: print("False") What will be printed… +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Mutable default argument Check whether the method mutates the list in place and what the list looks like after each call. Mutable default argument +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: You have four different blocks of code. Three of them return the same list, one of them returns something different. Apply the lambda/function to one element first, then extend that same transformation to the rest of th… +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Given s1 = 'abcd', which code fragment correctly updates s1 to 'Abcd'? Strings are immutable. s1.capitalize() returns a new string, so you must assign that result back to the name s1. String Methods +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do you include literal curly braces {} in an f-string? In f-strings, curly braces are escaped by doubling them ({{ and }}). F-strings +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: RuntimeError: dictionary changed size during iteration Adding or deleting dict entries while iterating over it causes RuntimeError +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What happens if you run print(df.iloc[5, 2]) on a DataFrame with only 3 rows? Unlike slicing, accessing a specific single position with .iloc that is out of bounds raises an IndexError. Selection with iloc +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Given s = pd.Series(['abc', 'xAef']), what is the result of s.str.upper().str.count('A').mean()? Upper becomes ['ABC', 'XAEF']. 'A' appears once in each, so counts are [1, 1]. The mean of [1, 1] is 1.0. Vectorized Opera… +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: During a .merge(how='left') operation, what is placed in a cell if no match is found in the right DataFrame? Pandas uses NaN (Not a Number) to represent missing data resulting from non-overlapping joins. Merging +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Why does Python interpret {x * 2 for x in l1} as a set comprehension and not a dictionary comprehension? Dictionary comprehensions require a 'key: value' syntax within the curly braces. Comprehensions +- `aiq-1` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What is the primary advantage of a generator over a list for large datasets? Generators do not store the entire sequence in memory, which is essential for very large or infinite datasets. Generators + +### Objects and Names + +- Snippet ID: `item:aiq-2` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `12` + +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Why does the following code work even though strings are immutable? Decide whether the code is rebinding a name or mutating a shared mutable object. Immutability/names +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Boolean operator precedence: not > and > or a==1 or a==2 and b==1 or b==2 is evaluated as a==1 or (a==2 and b==1) or b==2 +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Slicing negative step Read the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position. Slicing negative step +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Which update makes `library['books'] = 6` and adds `library['years']`? Check whether membership is testing keys, and trace any lookup or mutation on the dictionary. Exam • trial_midterm • Q8 +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: List method effects and resulting list Check whether the method mutates the list in place and what the list looks like after each call. Exam • midterm_2023 • Q16 Consider the following code snippet: mylist = [1, 3, 2, 3… +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: def multiply(num1, num2): multiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6. Exam • extra_practice •… +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Mutable arguments Mutating a passed list changes the caller's object; rebinding the parameter does not. Mutable arguments +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: You need to write a function called sort_list that accepts a list of integers. Check whether the method mutates the list in place and what the list looks like after each call. Exam • midterm_2023 • Q11 For example: If w… +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What does the slice s[::-2] do for the string s = 'abcdef'? The step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b'). String Slicing +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: If df.A has 3 elements, which operation will raise a ValueError? When broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together. Broadcasting Errors +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What is the result of {int(x) * 2 for x in '01212' if x in '02'}? Sets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored. Comprehensions +- `aiq-2` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: map/filter return iterables, not lists list(map(lambda x: x*2, l)) — must wrap in list(). Without it: + +### Objects and Names + +- Snippet ID: `item:aiq-3` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `9` + +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Assume you already have a variable called x, which contains a list of integers. Expand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time. Exam • trial_midterm… +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] a: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Correct. c: [::-1] reverses to [10,9,8,7,6,5,4,3,2,1], then [::2] tak… +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What does `list(x.values()) + list(x.keys())` print? Check whether membership is testing keys, and trace any lookup or mutation on the dictionary. Exam • trial_midterm • Q10 Suppose you have the following dictionary: x… +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: list Exam • midterm_2024 • Q22 Consider the following code snippet: x = ["a", "b", "c", "4"] print(x[-3] + x[3]*3) Which of the following code snippet will print the same output? +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Assume sum_even_in_list(l1) filters non-integers and sums even integers. a: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct ite… +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Suppose you have the following function: Trace the returned value, not just what gets printed while the function runs. Exam • midterm_2023 • Q9 Suppose you have the following function: def add_numbers(num1, num2 = 10, n… +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Suppose you have the following functions, one to elevates a number to square and the second elevates to cube: Apply the lambda/function to one element first, then extend that same transformation to the rest of the Serie… +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: map/filter return iterables, not lists list(map(lambda x: x*2, l)) — must wrap in list(). Without it: +- `aiq-3` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Slicing creates a NEW object l2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy + +### Objects and Names + +- Snippet ID: `item:aiq-4` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `6` + +- `aiq-4` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Suppose you have the following function: Trace the returned value, not just what gets printed while the function runs. Exam • trial_midterm • Q3 Suppose you have the following function: def multiply(*args, factor=2): to… +- `aiq-4` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Unordered collections equality {1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False +- `aiq-4` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Implicit return None Function without return statement, or where return is not reached, returns None. print(func()) will print None. +- `aiq-4` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword Check whether the method mutates the list in place and what the list looks like aft… +- `aiq-4` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: 1 + True = 2 (bool is subclass of int) True==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True +- `aiq-4` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Mutable default argument def f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function + +### Objects and Names + +- Snippet ID: `item:aiq-5` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `7` + +- `aiq-5` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Assume you have the following variables: Decide whether the code is rebinding a name or mutating a shared mutable object. Exam • trial_midterm • Q4 Assume you have the following variables: x = 3 y = 3.0 z = '3' What wil… +- `aiq-5` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: str.upper() / string methods don't modify in place s.upper() returns a new string; s is unchanged. Must do s = s.upper() +- `aiq-5` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Single-element tuple needs trailing comma (1) is int, not tuple. (1,) or 1, is a tuple +- `aiq-5` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: You have to write a function called summarize which take a list of integers as an argument. Return `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`. Exam • midterm_2024 • Q13 The… +- `aiq-5` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: map/filter return iterables, not lists list(map(lambda x: x*2, l)) — must wrap in list(). Without it: +- `aiq-5` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Slicing creates a NEW object l2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy +- `aiq-5` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: UnboundLocalError If a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line + +### Objects and Names + +- Snippet ID: `item:aiq-6` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `5` + +- `aiq-6` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Slicing creates a NEW object l2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy +- `aiq-6` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: range() and slicing both exclusive at stop range(1,10,3)→[1,4,7] not including 10; l[2:7] goes up to but not including index 7 +- `aiq-6` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: RuntimeError: dictionary changed size during iteration Adding or deleting dict entries while iterating over it causes RuntimeError +- `aiq-6` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Mutable default argument def f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function +- `aiq-6` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: range() and slicing both exclusive at stop range(1,10,3)→[1,4,7] not including 10; l[2:7] goes up to but not including index 7 + +### Objects and Names + +- Snippet ID: `item:aiq-7` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `2` + +- `aiq-7` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Mutable default argument def f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function +- `aiq-7` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Mutable parameter sharing When mutable object passed as argument, parameter and argument point to SAME object — mutations inside function affect original + +### Objects and Names + +- Snippet ID: `item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: What will be printed by the following code segment? a b c d b The type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`.… + +### Objects and Names + +- Snippet ID: `item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination. You want to write a program to advice Dutch residents on th… + +### Objects and Names + +- Snippet ID: `item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-Trial final exam Introduction to Python-3-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary in the students list has two keys: "Name" and "Grade". The corresponding values are student names (as strings… + +### Objects and Names + +- Snippet ID: `item:exam-extra_practice-11-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-extra_practice-11-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: x = ['abc', [[]], (1, 2), {}, True, 3.0, 4] What is the output of the following code snippet? print(type(float(x[2][0] + x[2][1])) == type(x[-2])) a b c d d x[2] = (1,2). x[2][0]=1, x[2][1]=2. 1+2=3. float(3)=3.0. type(… + +### Objects and Names + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-13-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z) A B C D A '3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is False. x == y == z evaluates as (x == y)… + +### Objects and Names + +- Snippet ID: `item:exam-midterm_2023-4-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-midterm_2023-4-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Assume you have the following variables: x = 'abc' y = 3 z = 2.0 What will be printed after these lines of code? print(x*y) print(x*z) print(y*z) A 'abcabcabc' The code will result in a TypeError because you can't multi… + +### Objects and Names + +- Snippet ID: `item:exam-midterm_2024-4-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-midterm_2024-4-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Consider the following code snippet: a = 1 b = 2.0 c = '3' d = 'hello' y = {} for i in [0,1]: if i==0: if type(a)==type(b): y[i] = True else: y[i] = False if i==1: if type(c)==type(d): y[i] = True else: y[i] = False pri… + +### Objects and Names + +- Snippet ID: `item:exam-midterm_2024-6-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-midterm_2024-6-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Consider the following code snippet: x = 10 y = '5' z = x + y ​What will be the value of 'z' and why? A The value of z will be 15 because the string '5' will be implicitly converted to an integer. B The value of z will… + +### Objects and Names + +- Snippet ID: `item:exam-trial-final-exam-py22-1-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial-final-exam-py22-1-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive). Which of the following programs will tell you whether x contains an odd or even number? a b c d d All three programs… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-1-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-1-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: Assume you already have a variable called x, which contains a list of integers. Which of the following programs will print you a list of the squared values of the elements in x? + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-11-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-11-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Consider the following code snippet: x = 10 y = '5' z = x + y ​What will be the value of 'z' and why? A The code will result in a None because 'x' and 'y' have different types. B The code will result in an error because… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-12-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-12-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Which other program will produce the same output as the following code snippet? + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-14-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-14-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Consider the following code snippet: a = 1 b = 2.0 c = '3' d = 'hello' y = {} for i in [0,1]: if i==0: if type(a)==type(b): y[i] = True else: y[i] = False if i==1: if type(c)==type(d): y[i] = True else: y[i] = False pri… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-15-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-15-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following function count_characters, which takes two arguments: a list of strings which are names, and an optional keyword argument called character that has a default value of 'a'. def count_charac… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-16-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-16-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: What is the output of the program below? + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-18-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-18-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following function which take a list of numerical strings as an argument. + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-20-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-20-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: You have the following list: my_list = [1,2,3,4] Which one of the following lines of code lines does not print 4 as the output? A print(my_list[4]) B print(my_list[-1]) C print(max(my_list)) D print(len(my_list)) + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-21-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-21-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Consider the following code snippet: x = ["a", "b", "c", "4"] print(x[-3] + x[3]*3) Which of the following code snippet will print the same output? A y = [1, 2, 3, 4] print('b'+ max(y)*3) B print('b' + str(len(x)*3)) C… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-22-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-22-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following a dictionary called students, which contains three sub-dictionaries: students = {"james": {"name": "James", "homework": [90.0, 97.0, 75.0, 92.0], "quizzes": [88.0, 40.0, 94.0], "tests": [7… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-24-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-24-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Consider the following code snippet: a = True b = False c = True d = False if not (a or b) and (c or d): print("True") else: print("False") What will be printed by the code? A The code will result in an error. B True C… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-3-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-3-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following function: def multiply(*args, factor=2): total = 1 for num in args: total *= num return total * factor Which of the following functions will return the same values as the function above, i… + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-4-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-4-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: Assume you have the following variables: x = 3 y = 3.0 z = '3' What will be printed by the following code: print((x != z and x == int(z)) or (x != y and y != z)) A 3 B The code will result in an error. C False D True + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-7-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-7-w1-objects-and-names` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called dict_keys that checks whether a certain key is in available in a certain dictionary. + +### Objects and Names + +- Snippet ID: `item:exam-trial_midterm-9-w1-objects-and-names` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `exam-trial_midterm-9-w1-objects-and-names` + Bucket: `additional` | Type: `source_exam` + Preview: Consider the following code snippet: mylist = [1, 2, 5, 7, 9, 12] new_list1 = mylist[0:3] new_list2 = mylist[1:4] print(new_list1 + new_list2) What will be printed? A [1, 2, 5, 7, 2, 5, 7, 9] B [1, 2, 5, 2, 5, 7] C [2,… + +### Objects and Names + +- Snippet ID: `item:kp-2-d1` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `20` + +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: List is mutable — can change element in place l1 = [1, 2, 3] print(l1) # [1, 2, 3] l1[2] = 4 print(l1) # [1, 2, 4] +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Float precision issue print(1.1 + 2.2 == 3.3) # False +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: range examples print(list(range(6))) # [0, 1, 2, 3, 4, 5] print(list(range(3,6))) # [3, 4, 5] print(list(range(3,6,2))) # [3, 5] +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Looping over dict capitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'} for key in capitals.keys(): print(key) for val in capitals.values(): print(val) for key, value in capitals.items(): print(key, value) #… +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Set operations countries = set() # empty set (NOT {}) countries = {'Andorra', 'Belgium'} print({1,2,2} == {2,1}) # True (duplicates ignored) print(len({1,2,2})) # 2 countries.remove('Andorra') countries.add('Greece') co… +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Explicit conversions print(str(1) == '1') # True print(int('1') == 1) # True print(int('1a')) # ERROR print(float('1') == 1.0) # True print(float('1.0') == 1.0) # True print(tuple([1,2,3]) == (1,2,3)) # True print(tuple… +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Method on immutable — must capture return value s1 = 'UVA Amsterdam' s1 = s1.upper() # CORRECT — captures new string s1.upper() # WRONG — result is lost, s1 unchanged +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Implicit None return def adder(n1, n2): if type(n1) == type(n2) == int: total = n1 + n2 return total a = adder('1', 2) # Returns None (no return hit) print(a) # None +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Keyword arguments def calc(first, second, third, fourth, fifth, sixth): return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth print(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63 +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Lambda basics add_two = lambda x, y: x + y print(add_two(1, 2)) # 3 # Equivalent to: def add_two(x, y): return x + y +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Newlines and tabs print('Line 1\nLine 2\tTabbed') print("It\'s a string") +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Slicing examples s = '01234567' print(s[::4]) # '04' print(s[::-2]) # '7531' +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Debug shortcut val = 10 print(f'{val=}') # 'val=10' +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Using self to access attributes class Dog: def __init__(self, name): self.name = name def bark(self): return f'{self.name} says woof!' +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Raising an error def check_positive(n): if n < 0: raise ValueError('Number must be positive') return n +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Select rows/cols by name df.loc['First':'Third', ['Name', 'Weight']] +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Scalar broadcasting df['Height'] += 10 # Adds 10 to every cell in the column +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Left join on a key df1.merge(df2, on='Town', how='left') +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Double vowels in a string s2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python']) +- `kp-2-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Manual iteration it = iter([1, 2]); print(next(it)); print(next(it)) + +### Objects and Names + +- Snippet ID: `item:kp-2-d2` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `7` + +- `kp-2-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Tuple is immutable — assigning to index raises TypeError t1 = (1, 2, 3) t1[2] = 4 # TypeError: 'tuple' object does not support item assignment +- `kp-2-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: List/tuple comparison print([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less) print([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0) +- `kp-2-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Iteration and ordering reminders Pattern | Iterates over | Trap for key in d | keys | same as for key in d.keys() for value in d.values() | values | no keys available unless you ask for them for key, value in d.items()… +- `kp-2-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Implicit conversion (Python allows with bool/numeric mix) print(1 + True) # 2 print(1.0 + False) # 1.0 print('1' * 2) # '11' print('1' * True) # '1' print('1' * False) # '' +- `kp-2-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Method on mutable — changes in place vs returns value l1 = [3, 1, 2] l1.sort() # changes l1 in place, returns None print(l1) # [1, 2, 3] print(l1.index(2)) # 1 (returns index, doesn't change l1) +- `kp-2-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: **kwargs def calc(**kwargs): return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third'] print(calc(third=4, second=2, first=3)) +- `kp-2-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: map() with lambda l1 = [1, 2, 3, 4, 5, 6] print(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12] # Need list() to convert map object to list + +### Objects and Names + +- Snippet ID: `item:kp-3-d1` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `13` + +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Basic assignment name_1 = 300 print(name_1) # 300 print(type(name_1)) # print(id(name_1)) # some unique integer +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Precedence trap a=1; b=3 print(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter) print((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT) +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: 1-element tuple gotcha t1 = (1) print(type(t1) == tuple) # False print(type(t1) == int) # True t1 = (1,) # correct 1-element tuple t1 = 1, # also correct x, y = y, x # swap using tuple unpacking +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Default value def multiplier(first, second=2): return first * second print(multiplier(3)) # 6 (uses default second=2) print(multiplier(3, 3)) # 9 print(multiplier(2, second=3)) # 6 +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Compact lambda / map reference Pattern | Meaning lambda x: x * 2 | inline function for one value map(f, seq) | apply `f` to each element lazily list(map(f, seq)) | materialize the mapped results for display +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Joining a list into a string words = ['a', 'b', 'c'] print('-'.join(words)) # 'a-b-c' print(''.join(words)) # 'abc' +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Zero-padding an integer num = 7 print(f'{num:03d}') # '007' +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Shared class attribute class Counter: count = 0 def __init__(self): Counter.count += 1 +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Specific exception handler s1 = 'abcdefghabcdefgh' needle = 'i' try: position = s1.index(needle) except ValueError: position = -1 print(position) +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Select by position df.iloc[0:2, 0:1] # Rows 0,1; Col 0 +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Chained string operations s.str.upper().str.count('A') +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Grouped aggregation df.groupby('Nationality')['Height'].median() +- `kp-3-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dictionary with sub-dictionaries result = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)} + +### Objects and Names + +- Snippet ID: `item:kp-3-d2` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `2` + +- `kp-3-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Two names bound to the same object (same id) name_3 = name_4 = name_5 = name_6 = 300 print(name_3 is name_4 is name_5 is name_6) # True +- `kp-3-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Mutable default BUG def main(addition, l1=[]): l1.append(addition) return l1 print(main(2)) # [2] print(main(3)) # [2, 3] ← BUG: l1 persists! + +### Objects and Names + +- Snippet ID: `item:kp-4-d1` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `7` + +- `kp-4-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: All 8 types var_1 = 123 # int var_2 = 123.3 # float var_3 = '123' # str var_4 = True # bool var_5 = ('123', 123) # tuple var_6 = [123, '123'] # list var_7 = {'k1': 'v1'} # dict var_8 = {123, '123'} # set +- `kp-4-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: pass as stub def adder(n1, n2): if type(n1) == int and type(n2) == int: result = n1 + n2 else: pass # placeholder — won't cause IndentationError return result +- `kp-4-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Limiting replacements s = 'aaaa' print(s.replace('a', 'b', 2)) # 'bbaa' +- `kp-4-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Padding with `.format(...)` score = 91 print('Score: {:04d}'.format(score)) +- `kp-4-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Series vs DataFrame result type(df.loc[2]) # Series type(df.loc[[2]]) # DataFrame +- `kp-4-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Filtering with isin vowels = list('aeiou') s[s.str[-1].str.lower().isin(vowels)] +- `kp-4-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Using walrus to avoid double squaring l1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10] + +### Objects and Names + +- Snippet ID: `item:kp-6-d1` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `5` + +- `kp-6-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Basic slicing examples l1 = [1, 2, 3, 4, 5, 6, 7, 8] print(l1[7]) # 8 print(l1[-1]) # 8 print(l1[-5:5]) # [4, 5] print(l1[:-5]) # [1, 2, 3] +- `kp-6-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Stripping whitespace and characters s = ' abc ' print(s.strip()) # 'abc' s2 = 'eeabcdee' print(s2.strip('e')) # 'abcd' +- `kp-6-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Valid vs invalid Pandas selection Code | Valid? | Meaning df.loc[2:4, ['B']] | yes | label-based rows + columns df.iloc[1:4, [1]] | yes | position-based rows + columns df.loc[df['A'] > 0, ['B', 'C']] | yes | boolean-mas… +- `kp-6-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Row-wise average df['Avg'] = df.apply(lambda x: x.mean(), axis=1) +- `kp-6-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Generator for large range gen = (x for x in range(1000000) if x % 3 == 0) + +### Objects and Names + +- Snippet ID: `item:kp-6-d2` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `3` + +- `kp-6-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Negative step l1 = [1, 2, 3, 4, 5, 6, 7, 8] print(l1[5:1:-2]) # [6, 4] print(l1[5::-1]) # [6, 5, 4, 3, 2, 1] print(l1[:1:-1]) # [8, 7, 6, 5, 4, 3] print(l1[1:5:-2]) # [] (already past end) +- `kp-6-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Even-index row pattern df.loc[df.index % 2 == 0, ['B']] +- `kp-6-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Columnwise mean df.loc['Av'] = df.apply(lambda col: col.mean(), axis=0) + +### Objects and Names + +- Snippet ID: `item:kp-7-d1` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `3` + +- `kp-7-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Simple function def size(length, width): return length * width print(size(2,3)) # 6 +- `kp-7-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Handling NaNs df.fillna('No value') # Replaces all NaNs +- `kp-7-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Filtering dictionary items d = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1} + +### Objects and Names + +- Snippet ID: `item:kp-manual-aliasing-copy-d1` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `kp-manual-aliasing-copy-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Aliasing vs slicing copy l1 = [1, 2, 3] l2 = l1 l3 = l1[:] l1[0] = 99 print(l2) # [99, 2, 3] print(l3) # [1, 2, 3] + +### Objects and Names + +- Snippet ID: `item:ks-0153de2f70` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-0153de2f70` + Bucket: `additional` | Type: `source_lecture` + Preview: Functions — basics Functions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects. Simple function def size… + +### Objects and Names + +- Snippet ID: `item:ks-419e787b39` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-419e787b39` + Bucket: `additional` | Type: `source_lecture` + Preview: objects ### Everything in Python is an object. Objects in Python have one id, one value, one type, and zero or more names
                    An assignment statement is one of the ways to create an object. An object created with an ass… + +### Objects and Names + +- Snippet ID: `item:ks-61c5deec4a` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-61c5deec4a` + Bucket: `recommended` | Type: `source_lecture` + Preview: Assignment statements — reading right to left Python creates a new object with the value on the right, infers type from the value, then binds the name on the left to that object. Basic assignment name_1 = 300 print(name… + +### Objects and Names + +- Snippet ID: `item:ks-6f41148083` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-6f41148083` + Bucket: `additional` | Type: `source_lecture` + Preview: Slicing Syntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type. Basic slici… + +### Objects and Names + +- Snippet ID: `item:ks-cb3a9e3fd2` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-cb3a9e3fd2` + Bucket: `recommended` | Type: `source_lecture` + Preview: Object types — the 8 types to know int, float, str, bool, tuple, list, dict, set All 8 types var_1 = 123 # int var_2 = 123.3 # float var_3 = '123' # str var_4 = True # bool var_5 = ('123', 123) # tuple var_6 = [123, '12… + +### Objects and Names + +- Snippet ID: `item:ks-d79a1899f6` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-d79a1899f6` + Bucket: `additional` | Type: `source_lecture` + Preview: Names / variable naming rules Names can consist of letters (upper/lower), digits, and underscores. Names CANNOT start with a digit. Names ARE case-sensitive (name_1 != Name_1). Avoid Python reserved words (e.g., don't n… + +### Objects and Names + +- Snippet ID: `item:ks-df3b849d59` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-df3b849d59` + Bucket: `additional` | Type: `source_lecture` + Preview: Exam question types Which code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output… + +### Objects and Names + +- Snippet ID: `item:ks-e88d0a8060` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-e88d0a8060` + Bucket: `recommended` | Type: `source_lecture` + Preview: Objects: core properties Every object has exactly one unique id (cannot change), exactly one type (cannot change), and exactly one value. The type defines what value can be stored and whether the value is mutable or imm… + +### Objects and Names + +- Snippet ID: `item:ks-eae9bf47dd` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `1` + +- `ks-eae9bf47dd` + Bucket: `recommended` | Type: `source_lecture` + Preview: Mutable vs immutable types Immutable: int, float, str, bool, tuple. Mutable: list, dict, set. The value of a mutable object CAN be changed in-place. The value of an immutable object CANNOT be changed — a new object must… + +### Objects, Types, Mutability, Assignment, and Names + +- Snippet ID: `subtopic:w1-objects-and-names:w1-objects-and-names-core` +- Topic: Objects and Names +- Card ID: `w1-objects-and-names` +- Piece count: `19` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: List is mutable — can change element in place l1 = [1, 2, 3] print(l1) # [1, 2, 3] l1[2] = 4 print(l1) # [1, 2, 4] Immutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Tuple is immutable — assigning to index raises TypeError t1 = (1, 2, 3) t1[2] = 4 # TypeError: 'tuple' object does not support item assignment Immutable types like `int`, `float`, `str`, and `tuple` cannot change in pla… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Basic assignment name_1 = 300 print(name_1) # 300 print(type(name_1)) # print(id(name_1)) # some unique integer Assignment binds the left-hand name to the object produced on the right-hand side. +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Two names bound to the same object (same id) name_3 = name_4 = name_5 = name_6 = 300 print(name_3 is name_4 is name_5 is name_6) # True Assignment binds the left-hand name to the object produced on the right-hand side. +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: All 8 types var_1 = 123 # int var_2 = 123.3 # float var_3 = '123' # str var_4 = True # bool var_5 = ('123', 123) # tuple var_6 = [123, '123'] # list var_7 = {'k1': 'v1'} # dict var_8 = {123, '123'} # set Core built-in t… +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Basic slicing examples l1 = [1, 2, 3, 4, 5, 6, 7, 8] print(l1[7]) # 8 print(l1[-1]) # 8 print(l1[-5:5]) # [4, 5] print(l1[:-5]) # [1, 2, 3] Syntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults… +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Negative step l1 = [1, 2, 3, 4, 5, 6, 7, 8] print(l1[5:1:-2]) # [6, 4] print(l1[5::-1]) # [6, 5, 4, 3, 2, 1] print(l1[:1:-1]) # [8, 7, 6, 5, 4, 3] print(l1[1:5:-2]) # [] (already past end) Syntax: seq[start:end:step]. S… +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Simple function def size(length, width): return length * width print(size(2,3)) # 6 Functions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Me… +- `manual-objects-aliasing` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Aliasing vs slicing copy l1 = [1, 2, 3] l2 = l1 l3 = l1[:] l1[0] = 99 print(l2) # [99, 2, 3] print(l3) # [1, 2, 3] For mutable objects, `l2 = l1` aliases the same object; use slicing like `l1[:]` when you need an indepe… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Each object has identity, type, and value. Names bind to objects; rebinding changes the name, while in-place changes only affect mutable objects. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Immutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the same object. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Assignment binds the left-hand name to the object produced on the right-hand side. +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Core built-in types: `int`, `float`, `str`, `bool`, `tuple`, `list`, `dict`, `set`. +- `kp-5` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Names can consist of letters (upper/lower), digits, and underscores. Names CANNOT start with a digit. Names ARE case-sensitive (name_1 != Name_1). Avoid Python reserved words (e.g., don't name a variable 'sorted', 'list… +- `kp-6` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Syntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type. +- `kp-7` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Functions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects. +- `kp-8` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Which code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others. +- `kp-9` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: Everything in Python is an object. Objects in Python have one id, one value, one type, and zero or more names An assignment statement is one of the ways to create an object. An object created with an assignment statemen… +- `kp-manual-aliasing-copy` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Objects, Types, Mutability, Assignment, and Names + Preview: For mutable objects, `l2 = l1` aliases the same object; use slicing like `l1[:]` when you need an independent copy. + +### Arithmetic, Comparison, and Boolean Operators + +- Snippet ID: `subtopic:w1-operators-and-truth:w1-operators-and-truth-core` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `11` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: Floor division and modulo print(5 // 3, 5 % 3) # 1 2 print(-5 // 3, -5 % 3) # -2 1 print(5 // 2, 5 % 2) # 2 1 print(-5 // 2, -5 % 2) # -3 1 a+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highe… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: Float precision issue print(1.1 + 2.2 == 3.3) # False ==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list compar… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: List/tuple comparison print([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less) print([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0) ==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: Precedence trap a=1; b=3 print(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter) print((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT) x and y: True only if both True. x or y: False only if both Fals… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: arithmetic_operators print(5//2, 5%2) 2 1 +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: arithmetic_operators print(4 + 3) print(4 - 3) print(4 * 3) print(4 / 3) print(4 / 2) print(4 ** 3) 7 1 12 1.3333333333333333 2.0 64 +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: arithmetic_operators print(5 // 3, 5 % 3) print(-5 // 3, -5 % 3) print(5 // 2, 5 % 2) print(-5 // 2, -5 % 2) 1 2 -2 1 2 1 -3 1 +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: `==` versus `is` # import random # The random module that can be used to generate pseudo-random numbers is part of the standard Python installation # but the name has still to be importent a = random.randint(3, 9) # Thi… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: a+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b)*b + a%b == a always. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: ==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differ… +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Arithmetic, Comparison, and Boolean Operators + Preview: x and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then 'or'. Use parenthes… + +### Operators and Truth + +- Snippet ID: `item:cs-266616a010` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `1` + +- `cs-266616a010` + Bucket: `recommended` | Type: `source_notebook` + Preview: arithmetic_operators print(5 // 3, 5 % 3) print(-5 // 3, -5 % 3) print(5 // 2, 5 % 2) print(-5 // 2, -5 % 2) 1 2 -2 1 2 1 -3 1 + +### Operators and Truth + +- Snippet ID: `item:cs-3cb4b8e8f9` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `1` + +- `cs-3cb4b8e8f9` + Bucket: `recommended` | Type: `source_notebook` + Preview: arithmetic_operators print(4 + 3) print(4 - 3) print(4 * 3) print(4 / 3) print(4 / 2) print(4 ** 3) 7 1 12 1.3333333333333333 2.0 64 + +### Operators and Truth + +- Snippet ID: `item:cs-4f8a5f420b` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `1` + +- `cs-4f8a5f420b` + Bucket: `recommended` | Type: `source_notebook` + Preview: arithmetic_operators # import random # The random module that can be used to generate pseudo-random numbers is part of the standard Python installation # but the name has still to be importent a = random.randint(3, 9) #… + +### Operators and Truth + +- Snippet ID: `item:cs-7eb8617d28` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `1` + +- `cs-7eb8617d28` + Bucket: `recommended` | Type: `source_notebook` + Preview: arithmetic_operators print(5//2, 5%2) 2 1 + +### Operators and Truth + +- Snippet ID: `item:kp-1-d1` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `20` + +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Floor division and modulo print(5 // 3, 5 % 3) # 1 2 print(-5 // 3, -5 % 3) # -2 1 print(5 // 2, 5 % 2) # 2 1 print(-5 // 2, -5 % 2) # -3 1 +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Pattern | Meaning | Example seq[i] | single element | x[-1] seq[a:b] | start inclusive, stop exclusive | x[1:4] seq[::-1] | reverse copy | x[::-1] seq[::2] | step through every other item | x[::2] +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Import styles import numpy numpy.random.randint(1, 10) # works import numpy as np np.random.randint(1, 10) # works numpy.random.randint(1, 10) # ERROR from numpy.random import randint randint(1, 10) # works from numpy.r… +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Creating and using dicts capitals = {} capitals = dict() capitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'} print(capitals['Belgium']) # Brussels del(capitals['Belgium']) # delete key capitals['Netherland… +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Ordering comparison print([1,2] == [2,1]) # False (ordered) print((1,2) == (2,1)) # False (ordered) print('12' == '21') # False (ordered) print({1,2} == {2,1}) # True (unordered) print({1:1,2:2}=={2:2,1:1}) # True (unor… +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Falsy values # All evaluate to False in a condition: [] # empty list () # empty tuple {} # empty dict set() # empty set '' # empty string 0 # zero int 0.0 # zero float +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Basic function def adder(n1, n2): total = n1 + n2 return total a = adder(1, 2) print(a) # 3 +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Returning a tuple (multiple values) def powers(n1): return n1 ** 2, n1 ** 3 # returns a tuple power2, power3 = powers(3) print(power2, power3) # 9 27 +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: *args usage def adder(*args): result = 0 for number in args: result += number return result print(adder(1, 2, 3, 4, 5)) # 15 +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Function factory def function_factory(increment): def adder(n1): return n1 + increment return adder add4 = function_factory(4) add5 = function_factory(5) print(add4(3)) # 7 print(add5(3)) # 8 +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Attempting to change a string s1 = 'abcd' s1.capitalize() # Returns 'Abcd' print(s1) # Still prints 'abcd' +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Behavior when substring is missing s = 'abc' print(s.find('z')) # -1 # print(s.index('z')) # Raises ValueError +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Simple f-string name = 'Jan' print(f'{name} studies Python.') # 'Jan studies Python.' +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Defining a simple class class Car: def __init__(self, color): self.color = color +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Handling a ValueError s = 'abc' try: idx = s.index('z') except ValueError: idx = -1 +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Summary stats print(df.describe()) +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Sorting by column values df.sort_values(by='Length', ascending=False) +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Vertical stack pd.concat([df1, df2], axis=0) +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Building a set of doubled odd numbers s1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0} +- `kp-1-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Simple step generator def count(start, stop, step): while start <= stop: yield start start += step + +### Operators and Truth + +- Snippet ID: `item:ks-03c874b8bb` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `1` + +- `ks-03c874b8bb` + Bucket: `recommended` | Type: `source_lecture` + Preview: Arithmetic operators a+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b… + +### Operators and Truth + +- Snippet ID: `item:ks-c0135e2a4a` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `1` + +- `ks-c0135e2a4a` + Bucket: `recommended` | Type: `source_lecture` + Preview: Comparison operators ==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left t… + +### Operators and Truth + +- Snippet ID: `item:ks-c815ffe1d5` +- Topic: Operators and Truth +- Card ID: `w1-operators-and-truth` +- Piece count: `1` + +- `ks-c815ffe1d5` + Bucket: `recommended` | Type: `source_lecture` + Preview: Boolean operators x and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then '… + +### Execution Model, Logical Lines, and Comments + +- Snippet ID: `subtopic:w1-python-basics:w1-python-basics-execution-model` +- Topic: Python Basics +- Card ID: `w1-python-basics` +- Piece count: `7` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Execution Model, Logical Lines, and Comments + Preview: print('Hello World') # Everything after the hashtag is a comment print('Hello World') # Everything after the hashtag is a comment Hello World +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Execution Model, Logical Lines, and Comments + Preview: print(_, __, ___) # print(_, __, ___) +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Execution Model, Logical Lines, and Comments + Preview: print('Hello World') print('Hello World') +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Execution Model, Logical Lines, and Comments + Preview: print(r"This gives no \" error") # print(r"This gives no \" error") print(r'This gives no \' error') +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Execution Model, Logical Lines, and Comments + Preview: line_joining a = 'Two or more physical lines can be joined' +\ ' with the help of backward slashes' print(a) +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Execution Model, Logical Lines, and Comments + Preview: line_joining a = ['Two or more physical lines can be joined', ' with the help of backward slashes'] print(a) +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Execution Model, Logical Lines, and Comments + Preview: Python script is translated line by line into byte code, then byte code is translated into machine code. Writing code must be precise; ambiguities that humans handle fine will cause Python errors. + +### Python Basics + +- Snippet ID: `item:cs-09e2b215ee` +- Topic: Python Basics +- Card ID: `w1-python-basics` +- Piece count: `1` + +- `cs-09e2b215ee` + Bucket: `recommended` | Type: `source_notebook` + Preview: print('Hello World') # Everything after the hashtag is a comment print('Hello World') # Everything after the hashtag is a comment Hello World + +### Python Basics + +- Snippet ID: `item:cs-814a07a136` +- Topic: Python Basics +- Card ID: `w1-python-basics` +- Piece count: `1` + +- `cs-814a07a136` + Bucket: `additional` | Type: `source_notebook` + Preview: 123*1 # 123*1 + +### Python Basics + +- Snippet ID: `item:ks-95be7f9418` +- Topic: Python Basics +- Card ID: `w1-python-basics` +- Piece count: `1` + +- `ks-95be7f9418` + Bucket: `recommended` | Type: `source_lecture` + Preview: Python execution model Python script is translated line by line into byte code, then byte code is translated into machine code. Writing code must be precise; ambiguities that humans handle fine will cause Python errors. + +### Python Basics + +- Snippet ID: `item:manual-comments` +- Topic: Python Basics +- Card ID: `w1-python-basics` +- Piece count: `1` + +- `manual-comments` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do comments start, and what does Python ignore after `#`? Everything after `#` on that logical line is ignored by Python. x = 3 # this comment does not execute print(x) + +### Python Basics + +- Snippet ID: `item:manual-logical-lines` +- Topic: Python Basics +- Card ID: `w1-python-basics` +- Piece count: `1` + +- `manual-logical-lines` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How can one logical line span multiple physical lines? Use open brackets or an explicit backslash to continue a statement across lines. numbers = [ 1, 2, 3, ] + +### Indexing, Slicing, and range() + +- Snippet ID: `subtopic:w1-sequences-and-access:w1-sequences-and-access-core` +- Topic: Sequences and Access +- Card ID: `w1-sequences-and-access` +- Piece count: `9` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Indexing, Slicing, and range() + Preview: range() output patterns print(list(range(6))) # [0, 1, 2, 3, 4, 5] print(list(range(3,6))) # [3, 4, 5] print(list(range(3,6,2))) # [3, 5] `range(start, stop, step)` excludes `stop`; defaults are `start=0` and `step=1`,… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Indexing, Slicing, and range() + Preview: print("This is a string") print("This is a string") print('This is another string') +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Indexing, Slicing, and range() + Preview: String quotes and escaping print("This gives no ' error") print('This gives no " error') +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Indexing, Slicing, and range() + Preview: a = 'This is a string' a = 'This is a string' b = "This is another string" print(a) print(b) print(a,b) +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Indexing, Slicing, and range() + Preview: a = 'This is a string'; b = 6; c = 0.0 # a = 'This is a string'; b = 6; c = 0.0 print(f"We know {a =}, {b= }, and {c = }") +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Indexing, Slicing, and range() + Preview: slicing l1 = ['a', 'b'] l2 = l1 l2[-1] = 'c' print(l1 == l3) l3 = l1[::] l3[-1] = 'c' print(l1 == l3) +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Indexing, Slicing, and range() + Preview: Negative indices count from the end: `seq[-1]` is last and `seq[-len(seq)]` is first. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Indexing, Slicing, and range() + Preview: `range(start, stop, step)` excludes `stop`; defaults are `start=0` and `step=1`, just like slicing excludes the stop index. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Indexing, Slicing, and range() + Preview: Pattern to remember: subset = numbers[::2][::-1] + +### Sequences and Access + +- Snippet ID: `item:cs-curated-hw-seq-nth-occurrence` +- Topic: Sequences and Access +- Card ID: `w1-sequences-and-access` +- Piece count: `1` + +- `cs-curated-hw-seq-nth-occurrence` + Bucket: `additional` | Type: `source_notebook` + Preview: Find the nth occurrence by advancing .index() x = ['A', 'B', 'A', 'C', 'B', 'A', 'B'] n = 2 i = -1 for _ in range(n): i = x.index('B', i + 1) print(i) 4 + +### Sequences and Access + +- Snippet ID: `item:cs-curated-hw-seq-slice-between-sentinels` +- Topic: Sequences and Access +- Card ID: `w1-sequences-and-access` +- Piece count: `1` + +- `cs-curated-hw-seq-slice-between-sentinels` + Bucket: `additional` | Type: `source_notebook` + Preview: Slice between two sentinel values without hard-coding indices x = [21, 15, 29, 20, 15, 21, 38, 26] left = x.index(15) + 1 right = left + x[left:].index(15) print(x[left:right]) [29, 20] + +### Sequences and Access + +- Snippet ID: `item:exam-extra_practice-6-w1-sequences-and-access` +- Topic: Sequences and Access +- Card ID: `w1-sequences-and-access` +- Piece count: `1` + +- `exam-extra_practice-6-w1-sequences-and-access` + Bucket: `recommended` | Type: `source_exam` + Preview: numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] Which of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]? a b c d d a: starts at -1 (10), step -2: [10,8,6,4,2]. Correct.… + +### Sequences and Access + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-18-w2-conditions` +- Topic: Sequences and Access +- Card ID: `w1-sequences-and-access` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-18-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: How do you break a list into a list of lists, where each sublist contains 3 elements? A B C D A Option A uses range(0, 7, 3) which generates 0, 3, 6. The slices x[0:3], x[3:6], and x[6:9] correctly partition the list. + +### Sequences and Access + +- Snippet ID: `item:ks-685cd3d828` +- Topic: Sequences and Access +- Card ID: `w1-sequences-and-access` +- Piece count: `1` + +- `ks-685cd3d828` + Bucket: `recommended` | Type: `source_lecture` + Preview: Indexing Forward: 0, 1, 2, ... len-1. Backward: -1 (last), -2 (second to last), ..., -len (first). l1[0] == l1[-len(l1)] + +### Sequences and Access + +- Snippet ID: `item:ks-be78ccac04` +- Topic: Sequences and Access +- Card ID: `w1-sequences-and-access` +- Piece count: `1` + +- `ks-be78ccac04` + Bucket: `recommended` | Type: `source_lecture` + Preview: range() range(start, stop, step). start default=0, step default=1. Stop is NOT inclusive. Works like slicing but defaults differ slightly. range examples print(list(range(6))) # [0, 1, 2, 3, 4, 5] print(list(range(3,6))… + +## Week 2 + +Snippet families in this group: **102** + +### Comparisons, `in`, Precedence, and Conditional Expressions + +- Snippet ID: `subtopic:w2-conditions:w2-conditions-core` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `6` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Comparisons, `in`, Precedence, and Conditional Expressions + Preview: Precedence trap a=1; b=3 # WRONG: Python evaluates 'and' before 'or' print(a==1 or a==2 and b==1 or b==2) # True (unexpected) # CORRECT: use brackets print((a==1 or a==2) and (b==1 or b==2)) # False Precedence (high to… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Comparisons, `in`, Precedence, and Conditional Expressions + Preview: Inclusion check — 'in' operator print(1 in [1,2,3]) # True print(1 in (1,2,3)) # True print('1' in '123') # True (substring) print(1 in {1:4, 2:3}) # True (checks keys) print(4 in {1:4, 2:3}) # False (4 is value, not ke… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Comparisons, `in`, Precedence, and Conditional Expressions + Preview: if/elif/else structure if condition_1: expression_1 elif condition_2: expression_2 expression_3 else: expression_4 if/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critic… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Comparisons, `in`, Precedence, and Conditional Expressions + Preview: Conditional expression (ternary) # Statement form: if a > 0: b = a else: b = 0 # Expression form: b = a if a > 0 else 0 # Even simpler: b = max(0, a) if/elif/else. One if at start, at most one else at end, unlimited eli… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Comparisons, `in`, Precedence, and Conditional Expressions + Preview: Comparison operators return booleans print(3 > 2) A comparison like `3 > 2` evaluates to either `True` or `False`. True +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Comparisons, `in`, Precedence, and Conditional Expressions + Preview: `not` flips booleans print(not True) print(not False) `not True` becomes `False` and `not False` becomes `True`. False True + +### Conditions + +- Snippet ID: `item:cs-curated-hw-conditions-first-match-wins` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `cs-curated-hw-conditions-first-match-wins` + Bucket: `additional` | Type: `source_notebook` + Preview: Branch order matters because the first matching condition wins x = [5, 10, 15, 20] a, b, c, d = 4, 9, 13, 15 result = [] for element in x: if element <= d: label = 'cat4' elif element >= c: label = 'cat3' elif element <… + +### Conditions + +- Snippet ID: `item:exam-Test Exam 07-06-22-4-w2-conditions` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `exam-Test Exam 07-06-22-4-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the ot… + +### Conditions + +- Snippet ID: `item:exam-midterm_2023-1-w2-conditions` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `exam-midterm_2023-1-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: What is the output of the following code snippet? + +### Conditions + +- Snippet ID: `item:exam-midterm_2024-2-w2-conditions` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `exam-midterm_2024-2-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: Assume you have the following variables: x = 3 y = 3.0 z = '3' What will be printed by the following code: print((x != z and x == int(z)) or (x != y and y != z)) A True B False C The code will result in an error. D 3 + +### Conditions + +- Snippet ID: `item:exam-trial_midterm-13-w2-conditions` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `exam-trial_midterm-13-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather alert system. + +### Conditions + +- Snippet ID: `item:exam-trial_midterm-6-w2-conditions` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `exam-trial_midterm-6-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: def main(lst, condition=lambda x: x): y = [] for x in lst: if condition(x): y.append(x) return y What will this function return, when called in the following way: main([1, 2, 3, 4, 5… + +### Conditions + +- Snippet ID: `item:kp-manual-precedence` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `kp-manual-precedence` + Bucket: `keyPoints` | Type: `key_point` + Preview: `not` binds tighter than `and`, and `and` binds tighter than `or`; add parentheses when the intended grouping is not obvious. + +### Conditions + +- Snippet ID: `item:kp-manual-ternary` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `kp-manual-ternary` + Bucket: `keyPoints` | Type: `key_point` + Preview: Use `x if cond else y` when both branches are single expressions; use a full `if/elif/else` block when the branches need multiple statements. + +### Conditions + +- Snippet ID: `item:ks-4b427a2425` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `ks-4b427a2425` + Bucket: `recommended` | Type: `source_lecture` + Preview: Conditions and boolean operators — precedence Precedence (high to low): comparisons → not → and → or. Use parentheses to be explicit. 'in' checks membership in sequence/set/dict-keys. Precedence trap a=1; b=3 # WRONG: P… + +### Conditions + +- Snippet ID: `item:ks-c19999c074` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `ks-c19999c074` + Bucket: `recommended` | Type: `source_lecture` + Preview: Conditional statements and expressions if/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critical — all code in a block must have same indentation. Conditional expression… + +### Conditions + +- Snippet ID: `item:manual-bool-precedence` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `manual-bool-precedence` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do `not`, `and`, and `or` combine when there are no extra parentheses? `not` is evaluated first, then `and`, then `or`, so parenthesize whenever the intended logic is not obvious. print(not False and True or False) + +### Conditions + +- Snippet ID: `item:manual-conditional-expression` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `manual-conditional-expression` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: When should you use `x if cond else y` instead of a multi-line `if/else` block? Use the conditional expression for a single value choice; use a full block when each branch needs multiple statements. label = 'pass' if sc… + +### Conditions + +- Snippet ID: `item:manual-filter-condition` +- Topic: Conditions +- Card ID: `w2-conditions` +- Piece count: `1` + +- `manual-filter-condition` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Trace `main(lst, condition)` and identify which values satisfy `lambda x: x % 2 != 0`. Apply the condition to one element first, then keep only the values for which it returns `True`. def main(lst, condition): return [x… + +### Conversion and Truthiness + +- Snippet ID: `item:cs-3e39a2f12f` +- Topic: Conversion and Truthiness +- Card ID: `w2-conversion-and-truthiness` +- Piece count: `1` + +- `cs-3e39a2f12f` + Bucket: `additional` | Type: `source_notebook` + Preview: type_conversion print ('1' * 2, '1' * True, '1' * False) + +### Conversion and Truthiness + +- Snippet ID: `item:cs-fc8bdeb969` +- Topic: Conversion and Truthiness +- Card ID: `w2-conversion-and-truthiness` +- Piece count: `1` + +- `cs-fc8bdeb969` + Bucket: `additional` | Type: `source_notebook` + Preview: type_conversion print (1==1.0, 1.0 == True, 0 == False) + +### Conversion and Truthiness + +- Snippet ID: `item:ks-d7e6d1b5b5` +- Topic: Conversion and Truthiness +- Card ID: `w2-conversion-and-truthiness` +- Piece count: `1` + +- `ks-d7e6d1b5b5` + Bucket: `recommended` | Type: `source_lecture` + Preview: Truthy and Falsy In conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers). Falsy values # All evaluate to False… + +### Conversion and Truthiness + +- Snippet ID: `item:ks-d9760d8cd8` +- Topic: Conversion and Truthiness +- Card ID: `w2-conversion-and-truthiness` +- Piece count: `1` + +- `ks-d9760d8cd8` + Bucket: `recommended` | Type: `source_lecture` + Preview: Type conversion (explicit) Python requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict(). Explicit conversions print(str(1) ==… + +### Explicit Conversion and Truthy/Falsy Rules + +- Snippet ID: `subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core` +- Topic: Conversion and Truthiness +- Card ID: `w2-conversion-and-truthiness` +- Piece count: `10` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Falsy values # All evaluate to False in a condition: [] # empty list () # empty tuple {} # empty dict set() # empty set '' # empty string 0 # zero int 0.0 # zero float In conditions, Python auto-converts to bool. Falsy:… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Explicit conversions print(str(1) == '1') # True print(int('1') == 1) # True print(int('1a')) # ERROR print(float('1') == 1.0) # True print(float('1.0') == 1.0) # True print(tuple([1,2,3]) == (1,2,3)) # True print(tuple… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Implicit conversion (Python allows with bool/numeric mix) print(1 + True) # 2 print(1.0 + False) # 1.0 print('1' * 2) # '11' print('1' * True) # '1' print('1' * False) # '' Python requires explicit conversion in most ca… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: str(1) versus int('1') print(str(1) == '1') print(int('1') == 1) +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Why `'1' + 2` raises `TypeError` try: print ('1' + 2) except Exception as e: print(e) +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Why `dict([1, 2])` raises `ValueError` try: print(dict([1, 2])) except Exception as e: print(e) +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Why `int('1a')` raises `ValueError` try: print(int('1a') == 1) except Exception as e: print(e) +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Truthy list in a `while` condition l1 = [1, 2, 3, 4, 5, 6] total = 0 while l1: total += l1[0] del l1[0] print(total) For numeric variables, `a += 1` updates the stored value the same way as `a = a + 1`. +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: In conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers). +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Explicit Conversion and Truthy/Falsy Rules + Preview: Python requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict(). + +### Creation, Lookup, Updates, and Key Constraints + +- Snippet ID: `subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `10` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Creating and using dicts capitals = {} capitals = dict() capitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'} print(capitals['Belgium']) # Brussels del(capitals['Belgium']) # delete key capitals['Netherland… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Dict membership checks KEYS, not values d = {1: 4, 2: 3} print(1 in d) # True (1 is a key) print(4 in d) # False (4 is a value, not a key) Dicts map unique immutable keys to values. `key in d` checks keys, and equality… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Dictionary creation and lookup squares = {1:1, 2:4, 3:9, 4:16} print(squares) l1 = [1, 2, 3, 4] l2 = [1, 4, 9, 16] squares = dict(zip(l1, l2)) print(squares) Check whether the code is looking up a key, iterating with `.… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Dictionary creation and lookup squares = {} print(squares) squares = dict() print(squares) Check whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary. +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Dictionary creation and lookup squares = {1:1, 2:4, 3:9, 4:16} del(squares[2]) print(squares) Check whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary. +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Dictionary creation and lookup a = 1 b = {1:1} print({a:b}) try: print({b:a}) except Exception as e: print(e) Check whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary. +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Dictionary creation and lookup capitals = {'Estonia': 'Tallinn', 'Belgium': 'Brussels', 'France': 'Paris'} print(capitals['Belgium']) Check whether the code is looking up a key, iterating with `.items()`, or mutating th… +- `manual-dict-construction-and-iteration` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Construct, iterate, count, and sort dictionaries words = ['pear', 'apple', 'pear'] counts = {} for word in words: counts[word] = counts.get(word, 0) + 1 print(dict(zip(['a', 'b'], [1, 2]))) for key in sorted(counts): pr… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Dicts map unique immutable keys to values. `key in d` checks keys, and equality ignores insertion order. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Creation, Lookup, Updates, and Key Constraints + Preview: Use `.keys()`, `.values()`, and `.items()` for dictionary views; looping over a dict directly gives keys. + +### Dictionaries and Mappings + +- Snippet ID: `item:cs-curated-hw-dict-delete-shared-keys` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `cs-curated-hw-dict-delete-shared-keys` + Bucket: `additional` | Type: `source_notebook` + Preview: Delete keys only when they also appear in a reference dict x = {'a': 1, 'b': 2, 'c': 3} to_remove = {'c': 3, 'd': 3} for key in to_remove: if key in x: del x[key] print(x) {'a': 1, 'b': 2} + +### Dictionaries and Mappings + +- Snippet ID: `item:cs-curated-hw-dict-digit-frequency` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `cs-curated-hw-dict-digit-frequency` + Bucket: `additional` | Type: `source_notebook` + Preview: Count only digit characters that actually appear x = ['1', 'a', 'X', '2', 'b', 'Y', '1', 'a', 'X', '1', 'a', 'X'] counts = {} for digit in '0123456789': if digit in x: counts[digit] = x.count(digit) print(counts) {'1':… + +### Dictionaries and Mappings + +- Snippet ID: `item:cs-curated-hw-dict-project-values-sorted-keys` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `cs-curated-hw-dict-project-values-sorted-keys` + Bucket: `additional` | Type: `source_notebook` + Preview: Sort keys first, then project values in that order x = {1: 3, 3: 4, 2: 5} sorted_keys = sorted(x.keys(), reverse=True) result = [x[key] for key in sorted_keys] print(result) [4, 5, 3] + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-Resit 22/23-7-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-Resit 22/23-7-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: Assume you already have a list of strings called words. You need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths. Which of the following code… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values. The ASCII (American Standard Code for Information Intercha… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five diffe… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: You have the following dictionary that represents the monthly sales of a store: monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800} You need to calculate the aver… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-extra_practice-12-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-extra_practice-12-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: def counter(y): x = {} for index, element in enumerate(y): if index != int(element) and int(element) % 2 == 0: x[element] = len(element) return x What will this function return when called as: counter(['12345678', '1',… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-extra_practice-3-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-extra_practice-3-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries: results = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}} You would like to cr… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-extra_practice-4-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-extra_practice-4-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82} You want to find and print the names of the students who scored above the average score. Which of the following code segments will work as… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-extra_practice-5-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-extra_practice-5-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: students = ['A','B','C','D','E','F'] grades = [9,10,9,11,10,9] You need to create a dictionary called grade_counts that counts the number of students in each grade level. Expected: {9:3, 10:2, 11:1} Which of the followi… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-extra_practice-8-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-extra_practice-8-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: x = {'a': [1, 2], 'b':[3, 4], 'c':[5, 6], 'd':[7, 8]} Which of the following lines of code will print True? a b c d d a: x['a'][1]=2, x['b'][0]=3, 2*3=6, x['c'][1]=6. True. b: x['b'][0]=3, x['c'][0]=5, 3+5=8, x['d'][1]=… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key? A B C D C Both methods correctly calculate the cumulative sums based on key values,… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: What is the result of the program comparing d1 (from zip) and d2 (from enumerate)? A B C D A Both d1 and d2 result in the same dictionary: {1: 2, 2: 3, 3: 4, 4: 5}. + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: The following codes all print the same value, except one. Which one? A B C D A Iterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two va… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2023-5-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2023-5-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: What is the output of the program below? + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2023-6-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2023-6-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following dictionary: sample_dict = { "name": "Kim", "age": 25, "birthdate": "3-2-1998", "city": "Amsterdam"} Suppose you want to create a dictionary that only contains the keys 'name' and 'city'. W… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2023-7-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2023-7-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following dictionary: closet = { "shirts" : 5, "colors" : ['red', 'yellow', 'blue', 'pink'] } You want to: - add a key "shoes" which has a value that is a list containing the strings "sneakers" and… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2023-8-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2023-8-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following function: def my_count_function(string): counts = {} for letter in string: counts[letter] = string.count(letter) return counts And you create the following two dictionaries: desk_count = m… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2024-10-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2024-10-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following dictionary: library = {"books": 5, "genres": ['action', 'romance', 'thriller', 'classics']} You want to: - add a key "years", of which the value is a list of strings that are the years of… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2024-11-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2024-11-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following function: def my_count_function(string): counts = {} for letter in string: if letter in counts: counts[letter] += 1 else: counts[letter] = 1 return counts And you create the following two… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2024-12-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2024-12-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following dictionary: x = {1: 10, 2: 20, 3: 30, 4: 40} What will the following line of code print? print(list(x.values()) + list(x.keys())) A [10, 20, 30, 40, 1, 2, 3, 4] B [11, 22, 33, 44] C This c… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2024-7-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2024-7-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following a dictionary called students, which contains three sub-dictionaries: students = {"james": {"name": "James", "homework": [90.0, 97.0, 75.0, 92.0], "quizzes": [88.0, 40.0, 94.0], "tests": [7… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-midterm_2024-8-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-midterm_2024-8-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: You need to write a function called dict_keys that checks whether a certain key is in available in a certain dictionary. + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols. That is, if we execute the following comma… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: You have two lists representing the names and ages of individuals: names = ['Alice', 'Bob', 'Charlie', 'David'] ages = [25, 30, 35, 40] You need to create a dictionary called person_dict where the keys are the names and… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: You have the following dictionary that represents the performance ratings of employees in a company: employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6} You need to find and print the name of… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial_midterm-10-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial_midterm-10-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following dictionary: x = {1: 10, 2: 20, 3: 30, 4: 40} What will the following line of code print? print(list(x.values()) + list(x.keys())) A This code will result in an error because you cannot con… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial_midterm-19-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial_midterm-19-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following function: def my_count_function(string): counts = {} for letter in string: if letter in counts: counts[letter] += 1 else: counts[letter] = 1 return counts And you create the following two… + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial_midterm-2-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial_midterm-2-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings. + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial_midterm-23-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial_midterm-23-w2-dictionaries-and-mappings` + Bucket: `additional` | Type: `source_exam` + Preview: You have to write a function called summarize which take a list of integers as an argument. + +### Dictionaries and Mappings + +- Snippet ID: `item:exam-trial_midterm-8-w2-dictionaries-and-mappings` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `exam-trial_midterm-8-w2-dictionaries-and-mappings` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following dictionary: library = {"books": 5, "genres": ['action', 'romance', 'thriller', 'classics']} You want to: - add a key "years", of which the value is a list of strings that are the years of… + +### Dictionaries and Mappings + +- Snippet ID: `item:kp-1-d3` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `kp-1-d3` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dense reference table Operation | What it gives | Exam note d[key] | value lookup | Key must exist key in d | membership on keys | not values d.items() | (key, value) pairs | good for loops d.update(...) | mutates dict… + +### Dictionaries and Mappings + +- Snippet ID: `item:kp-1-d4` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `kp-1-d4` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Construction and lookup patterns Pattern | What it does | Exam use {'a': 1} | literal dict | fastest way to show known pairs dict() | empty dict | start building inside a loop dict(zip(keys, values)) | pairs two iterabl… + +### Dictionaries and Mappings + +- Snippet ID: `item:kp-2-d3` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `kp-2-d3` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dictionary equality ignores insertion order print({1: 1, 2: 2} == {2: 2, 1: 1}) print([1, 2] == [2, 1]) + +### Dictionaries and Mappings + +- Snippet ID: `item:ks-65c4de2e9d` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `ks-65c4de2e9d` + Bucket: `recommended` | Type: `source_lecture` + Preview: Dictionaries Sets of key:value pairs. Keys must be unique and immutable (hashable). Dictionaries are unordered for equality ({1:1,2:2}=={2:2,1:1} is True). Cannot be sorted. You can check membership with 'in' — this che… + +### Dictionaries and Mappings + +- Snippet ID: `item:ks-adb6d9f967` +- Topic: Dictionaries and Mappings +- Card ID: `w2-dictionaries-and-mappings` +- Piece count: `1` + +- `ks-adb6d9f967` + Bucket: `recommended` | Type: `source_lecture` + Preview: Looping over dictionaries .keys() → key sequence. .values() → value sequence. .items() → sequence of (key, value) tuples. 'for key in dict' is the same as 'for key in dict.keys()'. Looping over dict capitals = {'Andorra… + +### Lists and Sets + +- Snippet ID: `item:exam-Resit 22/23-1-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-Resit 22/23-1-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have a list called x containing tuples. Which of the following lines of code will print True? a b c d d Option A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to… + +### Lists and Sets + +- Snippet ID: `item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have a list called x containing tuples, where x = [(1, 2), (3, 4), (5, 6), (7, 8)] Which of the following lines of code will print True? a b c d d Option A evaluates to 2 * 3 == 6 (True). Option B evaluates… + +### Lists and Sets + +- Snippet ID: `item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have a list called x, where: Which of the following code segments will print the following list? [5, 4, 3, 2, 1] a b c d c Option A creates a set (removing duplicates) and sorts it in reverse order, yielding… + +### Lists and Sets + +- Snippet ID: `item:exam-extra_practice-1-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-extra_practice-1-w2-lists-and-sets` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following function: def func1(l1): return len(list(l1))==len(set(l1)) Which of the functions below returns the same values as the function above, if we call it in any of the following ways? func1(l1… + +### Lists and Sets + +- Snippet ID: `item:exam-midterm_2023-15-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-midterm_2023-15-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: Assume you already have a variable a, which is an integer between 1 and 4. What is the ​output of the following ​code snippet? + +### Lists and Sets + +- Snippet ID: `item:exam-midterm_2023-16-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-midterm_2023-16-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: mylist = [1, 3, 2, 3, 4, 5, 3, 3] mylist.append('3') mylist.remove(3) print(mylist.count(3)) What will be the output? Hint: The remove() list method removes the first occurrence of t… + +### Lists and Sets + +- Snippet ID: `item:exam-midterm_2024-22-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-midterm_2024-22-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: x = ["a", "b", "c", "4"] print(x[-3] + x[3]*3) Which of the following code snippet will print the same output? A z = [["a", "b", "c"], [1, 2, 3, 4]] print(z[0][1] + str(z[1][3])*3) B… + +### Lists and Sets + +- Snippet ID: `item:exam-midterm_2024-23-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-midterm_2024-23-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: mylist = [1, 2, 5, 7, 9, 12] new_list1 = mylist[0:3] new_list2 = mylist[1:4] print(new_list1 + new_list2) What will be printed? A [1, 2, 5, 2, 5, 7] B [1, 2, 5, 7, 2, 5, 7, 9] C [2,… + +### Lists and Sets + +- Snippet ID: `item:exam-midterm_2024-24-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-midterm_2024-24-w2-lists-and-sets` + Bucket: `additional` | Type: `source_exam` + Preview: You have the following list: my_list = [1,2,3,4] Which one of the following lines of code lines does not print 4 as the output? A print(max(my_list)) B print(len(my_list)) C print(my_list[4]) D print(my_list[-1]) + +### Lists and Sets + +- Snippet ID: `item:exam-trial-final-exam-py22-7-w2-lists-and-sets` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `exam-trial-final-exam-py22-7-w2-lists-and-sets` + Bucket: `recommended` | Type: `source_exam` + Preview: What is the output of the following code segment? a b c d c The list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions. + +### Lists and Sets + +- Snippet ID: `item:ks-08ac820c2f` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `ks-08ac820c2f` + Bucket: `recommended` | Type: `source_lecture` + Preview: Sets Unordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update(). Set operations countries = set() # empty set (… + +### Lists and Sets + +- Snippet ID: `item:ks-4258f15a6c` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `1` + +- `ks-4258f15a6c` + Bucket: `recommended` | Type: `source_lecture` + Preview: Lists vs Dictionaries vs Sets — ordered/unordered Lists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections. Ordering comparison print([1,2] ==… + +### Sequences, Uniqueness, and Common Operations + +- Snippet ID: `subtopic:w2-lists-and-sets:w2-lists-and-sets-core` +- Topic: Lists and Sets +- Card ID: `w2-lists-and-sets` +- Piece count: `10` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Ordering comparison print([1,2] == [2,1]) # False (ordered) print((1,2) == (2,1)) # False (ordered) print('12' == '21') # False (ordered) print({1,2} == {2,1}) # True (unordered) print({1:1,2:2}=={2:2,1:1}) # True (unor… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Set operations countries = set() # empty set (NOT {}) countries = {'Andorra', 'Belgium'} print({1,2,2} == {2,1}) # True (duplicates ignored) print(len({1,2,2})) # 2 countries.remove('Andorra') countries.add('Greece') co… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Create a list literal squares = [1, 4, 9, 16] print(squares) +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Delete by index with `del` squares = [1, 4, 5, 9, 16] del(squares[2]) print(squares) +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Two ways to create an empty list squares = [] print(squares) squares = list() print(squares) +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Lists are mutable: replace by index squares = [1, 4, 8, 15] squares[2] = 9 squares[3] = 16 print(squares) +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: List method effects and resulting list squares = [1, 4, 9, 16] squares.append(16) squares.append(25) print(squares) Check whether the method mutates the list in place and what the list looks like after each call. +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: List method effects and resulting list if 16 not in squares: squares.append(16) if 25 not in squares: squares.append(25) print(squares) Check whether the method mutates the list in place and what the list looks like aft… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Lists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sequences, Uniqueness, and Common Operations + Preview: Unordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update(). + +### for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + +- Snippet ID: `subtopic:w2-loops:w2-loops-core` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `8` + +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: Skip certain values with `continue` total = 0 for number in [1, 2, '3', 3, 5, 7]: if type(number) == str: continue total += number print(total) # 18 Use `continue` to ignore the current item and jump straight to the nex… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: Loop variable not used — use _ for _ in range(5): print('Hello') # prints Hello 5 times Use `_` when the loop should repeat a fixed number of times but the loop variable itself is not needed. Hello Hello Hello Hello Hel… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: `enumerate(seq, start=1)` countries = ['Andorra', 'Belgium'] for index, country in enumerate(countries, 1): print(country, 'has index:', index) # Andorra has index: 1 # Belgium has index: 2 Use `enumerate` when you need… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: `zip(a, b)` pairs items in parallel countries = ['Andorra', 'Belgium'] capitals = ['Andorra la Vella', 'Brussels'] for country, capital in zip(countries, capitals): print(country, 'has capital:', capital) Use `zip` when… +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: `while items:` repeats until the list is empty l1 = [1, 2, 3, 4, 5, 6] total = 0 while l1: # truthy while list is non-empty total += l1[0] del l1[0] print(total) # 21 Non-empty lists are truthy and empty lists are falsy… +- `manual-loop-max-sublist-sum` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: Keep the sub-list whose elements have the largest sum lists = [[1, 2], [4, 4], [3, 3, 1]] best = lists[0] for current in lists[1:]: if sum(current) > sum(best): best = current print(best) Store the current best sub-list… +- `manual-loop-zip-enumerate-membership` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: Combine `zip`, `enumerate`, unpacking, and membership names = ['Ada', 'Bob', 'Cleo'] scores = [8, 5] for index, (name, score) in enumerate(zip(names, scores), start=1): passed = score in {5, 6, 7, 8, 9, 10} print(index,… +- `kp-iteration-traps` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: for, while, Dictionary Iteration, enumerate(), zip(), and Walrus + Preview: `zip` stops at the shortest iterable, `in` checks membership, `//` floors division, `%` gives the remainder, and `sum(condition for ...)` counts how many times the condition is true. + +### Loops + +- Snippet ID: `item:cs-curated-hw-loops-enumerate-mark-max` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `cs-curated-hw-loops-enumerate-mark-max` + Bucket: `additional` | Type: `source_notebook` + Preview: Use enumerate() to keep indices while relabeling one special case x = [65, 43, 1, 0, 59, 16, 86, 40, 60] max_value = max(x) result = {} for index, value in enumerate(x): key = 'highest' if value == max_value else index… + +### Loops + +- Snippet ID: `item:cs-curated-hw-loops-market-clearing` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `cs-curated-hw-loops-market-clearing` + Bucket: `additional` | Type: `source_notebook` + Preview: Flatten, sort, and zip demand/supply curves to count trades buyers = {'buyer1': [24, 16, 13, 6, 5], 'buyer2': [23, 21, 19, 10, 7], 'buyer3': [21, 20, 15, 13, 10], 'buyer4': [20, 17, 9, 6, 5]} sellers = {'seller1': [8, 1… + +### Loops + +- Snippet ID: `item:cs-curated-hw-loops-nested-pairwise-dict` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `cs-curated-hw-loops-nested-pairwise-dict` + Bucket: `additional` | Type: `source_notebook` + Preview: Nested loops can build pairwise results for every combination def main(minimum, maximum): result = {} for first in range(minimum, maximum + 1): for second in range(minimum, maximum + 1): result[(first, second)] = first… + +### Loops + +- Snippet ID: `item:cs-curated-hw-loops-zip-filter-pairs` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `cs-curated-hw-loops-zip-filter-pairs` + Bucket: `additional` | Type: `source_notebook` + Preview: zip() aligns two lists so you can filter pairs into a dict keys = [3, 2, 1, 4] values = [3, 37, 60, 79] result = {} for key, value in zip(keys, values): if key != value and value % 5: result[key] = value print(result) {… + +### Loops + +- Snippet ID: `item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-Test Resit - Introduction to Python - 22/23-4-w2-loops` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following function, which takes two integers as arguments: What will be printed by the following line of code: print(main(1)) a b c d b The function uses y=11 as a default argument. The while loop r… + +### Loops + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-14-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-14-w2-loops` + Bucket: `recommended` | Type: `source_exam` + Preview: Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous). A B C D B Option B correctly updates the 'previous' state at the end of ea… + +### Loops + +- Snippet ID: `item:exam-midterm_2023-14-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2023-14-w2-loops` + Bucket: `recommended` | Type: `source_exam` + Preview: Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = "abcdefghijklmnopqrstuvwxyz" Which of the following code snippets will give the same output as the following command? print(l… + +### Loops + +- Snippet ID: `item:exam-midterm_2023-2-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2023-2-w2-loops` + Bucket: `recommended` | Type: `source_exam` + Preview: What is the output of the following code snippet? + +### Loops + +- Snippet ID: `item:exam-midterm_2024-17-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2024-17-w2-loops` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following function which take a list of numerical strings as an argument. + +### Loops + +- Snippet ID: `item:exam-midterm_2024-18-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2024-18-w2-loops` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have the following function count_characters, which takes two arguments: a list of strings which are names, and an optional keyword argument called character that has a default value of 'a'. def count_charac… + +### Loops + +- Snippet ID: `item:exam-midterm_2024-20-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2024-20-w2-loops` + Bucket: `additional` | Type: `source_exam` + Preview: What is the output of the program below? + +### Loops + +- Snippet ID: `item:exam-midterm_2024-21-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2024-21-w2-loops` + Bucket: `additional` | Type: `source_exam` + Preview: Assume you already have a variable called x, which contains a list of integers. Which of the following programs will print you a list of the squared values of the elements in x? + +### Loops + +- Snippet ID: `item:exam-midterm_2024-3-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2024-3-w2-loops` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: i = 1 while True: if i % 2 == 0: i += 1 continue elif i == 7: break else: print(i) i += 1 Which of the following code snippets will print the same output? A for i in range(1, 5, 2):… + +### Loops + +- Snippet ID: `item:exam-midterm_2024-9-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-midterm_2024-9-w2-loops` + Bucket: `additional` | Type: `source_exam` + Preview: Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings. + +### Loops + +- Snippet ID: `item:exam-trial_midterm-5-w2-loops` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `exam-trial_midterm-5-w2-loops` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: i = 1 while True: if i % 2 == 0: i += 1 continue elif i == 7: break else: print(i) i += 1 Which of the following code snippets will print the same output? A for i in range(1, 5, 2):… + +### Loops + +- Snippet ID: `item:kp-iteration-traps-d1` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `kp-iteration-traps-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Iteration helpers and operator traps Pattern | Returns / does | Trap zip(a, b) | pairs items in parallel | extra items in the longer iterable are ignored x in d | checks dict keys | not dict values a // b | floor divisi… + +### Loops + +- Snippet ID: `item:kp-manual-break-continue` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `kp-manual-break-continue` + Bucket: `keyPoints` | Type: `key_point` + Preview: `break` exits the loop immediately; `continue` skips the rest of the current iteration and moves to the next one. + +### Loops + +- Snippet ID: `item:kp-manual-enumerate` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `kp-manual-enumerate` + Bucket: `keyPoints` | Type: `key_point` + Preview: `enumerate(seq, start)` gives `(index, value)` pairs; `zip(a, b)` gives tuples of items from multiple iterables in parallel. + +### Loops + +- Snippet ID: `item:kp-manual-enumerate-d1` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `kp-manual-enumerate-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Start offset and tuple unpacking letters = ['a', 'b', 'c'] for index, letter in enumerate(letters, start=1): print(index, letter) for left, right in zip(['x', 'y'], [10, 20]): print(left, right) + +### Loops + +- Snippet ID: `item:kp-manual-loop-core` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `kp-manual-loop-core` + Bucket: `keyPoints` | Type: `key_point` + Preview: Use `for` when you already have an iterable; use `while` when repetition should continue only while a condition stays `True`. + +### Loops + +- Snippet ID: `item:kp-manual-loop-core-d1` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `kp-manual-loop-core-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Pick the loop shape first Pattern | Use when | Common exam note for item in seq | you need the values | prefer this over indexing when position is irrelevant for i, item in enumerate(seq, start) | you need both index an… + +### Loops + +- Snippet ID: `item:kp-manual-while-truthy` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `kp-manual-while-truthy` + Bucket: `keyPoints` | Type: `key_point` + Preview: A `while` condition is checked before every iteration, so a list loop like `while items:` keeps going only while the list is non-empty. + +### Loops + +- Snippet ID: `item:ks-4c6274845e` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `ks-4c6274845e` + Bucket: `recommended` | Type: `source_lecture` + Preview: zip() Loops over multiple sequences in parallel. Zips sequences of equal length (Python handles unequal lengths but it can be messy). Can zip sequences of different types. Can zip more than 2. zip two lists countries =… + +### Loops + +- Snippet ID: `item:ks-59aaf6b0ee` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `ks-59aaf6b0ee` + Bucket: `recommended` | Type: `source_lecture` + Preview: enumerate() Provides index alongside value when looping. enumerate(seq, start) — second arg sets the start index (default 0). enumerate with start=1 countries = ['Andorra', 'Belgium'] for index, country in enumerate(cou… + +### Loops + +- Snippet ID: `item:ks-624034d573` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `ks-624034d573` + Bucket: `additional` | Type: `source_lecture` + Preview: Walrus operator := Introduced in Python 3.8. Assigns AND evaluates to a value (unlike = which is a statement). Useful in while conditions to assign and test at once. Walrus in while loop total = 0 while (number := int(i… + +### Loops + +- Snippet ID: `item:ks-72c9eada91` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `ks-72c9eada91` + Bucket: `recommended` | Type: `source_lecture` + Preview: Augmented assignment operators Shorthand for a = a OP b. All arithmetic operators have an augmented form. All augmented operators a += 1 # a = a + 1 a -= 2 # a = a - 2 a *= 3 # a = a * 3 a /= 4 # a = a / 4 a //= 5 # a =… + +### Loops + +- Snippet ID: `item:ks-8ad541fef7` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `ks-8ad541fef7` + Bucket: `additional` | Type: `source_lecture` + Preview: While-loops while condition: expression. Checks condition BEFORE each execution. Use break and continue. Watch for infinite loops (Ctrl+C to exit). Use when you don't know beforehand how many iterations are needed. For-… + +### Loops + +- Snippet ID: `item:ks-bddafc66a0` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `ks-bddafc66a0` + Bucket: `recommended` | Type: `source_lecture` + Preview: For-loops for variable in sequence: expression. break: exit loop entirely. continue: skip to next iteration. You don't have to use the loop variable; use _ as convention when not needed. For-loop with continue total = 0… + +### Loops + +- Snippet ID: `item:manual-break-continue` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `manual-break-continue` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What is the difference between `break` and `continue` inside a loop? `break` exits the loop immediately; `continue` skips the rest of the current iteration and moves to the next one. for x in data: if x < 0: continue if… + +### Loops + +- Snippet ID: `item:manual-enumerate-zip` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `manual-enumerate-zip` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: When do you reach for `enumerate` versus `zip`? Use `enumerate(seq)` when you need index and value together; use `zip(a, b)` when you need items from multiple iterables in parallel. for i, value in enumerate(seq): ... f… + +### Loops + +- Snippet ID: `item:manual-loop-translate` +- Topic: Loops +- Card ID: `w2-loops` +- Piece count: `1` + +- `manual-loop-translate` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Translate `alphabet[1::2]` into a loop that collects every second character starting at index 1. Initialize an empty result, loop over the needed indices, and append the selected characters in order. result = '' for i i… + +## Week 3 + +Snippet families in this group: **65** + +### Arguments + +- Snippet ID: `item:exam-Resit 22/23-4-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-Resit 22/23-4-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following function, which takes two integers as arguments: What will be printed by the following line of code: print(main(1)) a b c d a The function `main` is called with `x=1`. `y` defaults to 11.… + +### Arguments + +- Snippet ID: `item:exam-Resit 22/23-6-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-Resit 22/23-6-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments. For example, if you call the function as: mai… + +### Arguments + +- Snippet ID: `item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments. For example, if you call the function as: mai… + +### Arguments + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-23-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-23-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: Which of the following function calls would return the number 30 as a result? A B C D C The first call sums (6+7+8+9)=30. The second call sums (1+4+9+16)=30. + +### Arguments + +- Snippet ID: `item:exam-midterm_2023-10-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-midterm_2023-10-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword arguments. The function should return a dictionary with name, age, and all other ke… + +### Arguments + +- Snippet ID: `item:exam-midterm_2023-9-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-midterm_2023-9-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following function: def add_numbers(num1, num2 = 10, num3 = 20): return num1 + num2 + num3 What are the outputs if we call the function three times as follows: add_numbers(5, 15) add_numbers(5, num3… + +### Arguments + +- Snippet ID: `item:exam-midterm_2024-13-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-midterm_2024-13-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: You have to write a function called summarize which take a list of integers as an argument. + +### Arguments + +- Snippet ID: `item:exam-midterm_2024-14-w3-arguments` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `exam-midterm_2024-14-w3-arguments` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following function: def multiply(*args, factor=2): total = 1 for num in args: total *= num return total * factor Which of the following functions will return the same values as the function above, i… + +### Arguments + +- Snippet ID: `item:kp-manual-args-kwargs-return-d1` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `kp-manual-args-kwargs-return-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Flexible signature reference Piece | Meaning first, second=0 | fixed parameters, one with a default *args | extra positional arguments as a tuple **kwargs | extra keyword arguments as a dict return a, b | returns one tu… + +### Arguments + +- Snippet ID: `item:ks-40fee04740` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `ks-40fee04740` + Bucket: `recommended` | Type: `source_lecture` + Preview: *args — undefined number of positional arguments Prefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python f… + +### Arguments + +- Snippet ID: `item:ks-d26b85265c` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `ks-d26b85265c` + Bucket: `recommended` | Type: `source_lecture` + Preview: Default arguments Default values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — n… + +### Arguments + +- Snippet ID: `item:ks-f5d65c7e89` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `1` + +- `ks-f5d65c7e89` + Bucket: `recommended` | Type: `source_lecture` + Preview: Keyword arguments and **kwargs Arguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs. Keyw… + +### Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + +- Snippet ID: `subtopic:w3-arguments:w3-arguments-core` +- Topic: Arguments +- Card ID: `w3-arguments` +- Piece count: `13` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: *args usage def adder(*args): result = 0 for number in args: result += number return result print(adder(1, 2, 3, 4, 5)) # 15 Prefixing a parameter with * makes Python collect all extra positional arguments into a tuple… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Mix defined and *args def adder(n1, n2, *args): result = n1 + n2 for number in args: result += number return result print(adder(1, 2, 3, 4, 5)) # 15 Prefixing a parameter with * makes Python collect all extra positional… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Keyword arguments def calc(first, second, third, fourth, fifth, sixth): return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth print(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63 Arguments… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: `**kwargs` behaves like a dict def calc(**kwargs): return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third'] print(calc(third=4, second=2, first=3)) Arguments can be passed by name (keyword). **kwargs collects und… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Default value def multiplier(first, second=2): return first * second print(multiplier(3)) # 6 (uses default second=2) print(multiplier(3, 3)) # 9 print(multiplier(2, second=3)) # 6 Default values are part of the functio… +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Mutable default BUG def main(addition, l1=[]): l1.append(addition) return l1 print(main(2)) # [2] print(main(3)) # [2, 3] ← BUG: l1 persists! Default values are part of the function HEADER (not the call). When argument… +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Return value with required positional args def adder(n1, n2): return n1 + n2 print(adder(1, 2)) Trace the returned value, not just what gets printed while the function runs. +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Default argument still returns one value def multiplier(first, second=2): return first * second print(multiplier(3)) Trace the returned value, not just what gets printed while the function runs. +- `manual-args-kwargs-return` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Flexible header plus tuple return def collect(first, *args, scale=1, **kwargs): return first * scale, args, kwargs result, extras, options = collect(2, 3, 4, scale=10, unit='cm') print(result) print(extras) print(option… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Prefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into arg… +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Arguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: Default values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable d… +- `kp-manual-args-kwargs-return` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps + Preview: A flexible header can mix fixed parameters, defaults, `*args`, and `**kwargs`, and a `return a, b` statement sends one tuple back to the caller that can be unpacked later. + +### def, Calls, and Methods vs Functions + +- Snippet ID: `subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `7` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: def, Calls, and Methods vs Functions + Preview: Define, call, and return a value def adder(n1, n2): total = n1 + n2 return total a = adder(1, 2) print(a) # 3 Define with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a lis… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: def, Calls, and Methods vs Functions + Preview: Wrong bracket errors print[1] # TypeError: 'function' object is not subscriptable l1 = [1,2,3] l1(1) # TypeError: 'list' object is not callable Define with `def name(params):` and call with `()`. `f[3]` tries to index,… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: def, Calls, and Methods vs Functions + Preview: Method on immutable — must capture return value s1 = 'UVA Amsterdam' s1 = s1.upper() # CORRECT — captures new string s1.upper() # WRONG — result is lost, s1 unchanged Methods are functions attached to objects. Some muta… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: def, Calls, and Methods vs Functions + Preview: `list.sort()` mutates in place and returns `None` l1 = [3, 1, 2] l1.sort() # changes l1 in place, returns None print(l1) # [1, 2, 3] print(l1.index(2)) # 1 (returns index, doesn't change l1) Mutating methods and value-r… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: def, Calls, and Methods vs Functions + Preview: Define with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a list and raises `TypeError`. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: def, Calls, and Methods vs Functions + Preview: Methods are functions attached to objects. Some mutate the object in place, while others return a value; string methods always return a new string. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: def, Calls, and Methods vs Functions + Preview: Function skeleton: `def f(x): return result`. Define with `def ...`, call with `()`, and use `[]` only for indexing. + +### Defining and Calling Functions + +- Snippet ID: `item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format: "https://www.[SECOND-LEVEL DOMAIN].… + +### Defining and Calling Functions + +- Snippet ID: `item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the ot… + +### Defining and Calling Functions + +- Snippet ID: `item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, bu… + +### Defining and Calling Functions + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key? A B C D A This is a standard dictionary comp… + +### Defining and Calling Functions + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: What will be printed by the function calls in the main function provided? A B C D D The function checks if all elements in the input list are either all empty or all non-empty. For the sets and lists provided, they are… + +### Defining and Calling Functions + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions` + Bucket: `recommended` | Type: `source_exam` + Preview: Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: "Name" and "Grade". You'd like to print the text: [NAME] has received a grade of [GRADE], with the… + +### Defining and Calling Functions + +- Snippet ID: `item:ks-ab66f3bab6` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `ks-ab66f3bab6` + Bucket: `recommended` | Type: `source_lecture` + Preview: Methods vs functions Methods are functions attached to objects. Calling obj.method() is equivalent to Class.method(obj). For mutable objects: some methods CHANGE the object (e.g. list.sort()), some RETURN a value (e.g.… + +### Defining and Calling Functions + +- Snippet ID: `item:ks-e09d7f145b` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `ks-e09d7f145b` + Bucket: `recommended` | Type: `source_lecture` + Preview: Function definition and calling def keyword, function name, parameters in parentheses, colon, indented body. Call with round brackets (). Using [] gives TypeError 'not subscriptable'. Using [] on a list with () gives Ty… + +### Defining and Calling Functions + +- Snippet ID: `item:manual-call-vs-index` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `manual-call-vs-index` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What error do you get from `print[1]` and from `[1, 2, 3](0)`? `print[1]` tries to subscript a function, while `[1, 2, 3](0)` tries to call a list. Both raise `TypeError`, but for opposite reasons. print[1] [1, 2, 3](0) + +### Defining and Calling Functions + +- Snippet ID: `item:manual-list-of-dicts-loop` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `manual-list-of-dicts-loop` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do you access values when looping over a list of dictionaries? Each loop iteration gives one dictionary, so read fields with keys like `student['Name']` and `student['Grade']`. for student in students: print(student… + +### Defining and Calling Functions + +- Snippet ID: `item:manual-string-return-shape` +- Topic: Defining and Calling Functions +- Card ID: `w3-defining-and-calling-functions` +- Piece count: `1` + +- `manual-string-return-shape` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do you recognize that a function should `return` a string instead of `print` it? If the result must be reused later, the function should `return` the string so the caller can store, combine, or print it afterwards.… + +### Higher-Order Patterns + +- Snippet ID: `item:cs-curated-hw-hof-nested-helper-hhi` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `cs-curated-hw-hof-nested-helper-hhi` + Bucket: `additional` | Type: `source_notebook` + Preview: A nested helper can hide repeated domain math inside one outer function def main(sales_before_entry): def calculate_hhi(sales_volumes): total_sales = sum(sales_volumes) return sum(round(100 * volume / total_sales) ** 2… + +### Higher-Order Patterns + +- Snippet ID: `item:exam-extra_practice-10-w3-higher-order-patterns` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `exam-extra_practice-10-w3-higher-order-patterns` + Bucket: `additional` | Type: `source_exam` + Preview: You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num. Example: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)]. Note: (6,5) is no… + +### Higher-Order Patterns + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns` + Bucket: `recommended` | Type: `source_exam` + Preview: What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2)) A B C D D list_1[0](1, 2) is 1 + 2 = 3. list_1[1](1, 2) is 1 * 2 = 2. 3 ** 2 = 9. + +### Higher-Order Patterns + +- Snippet ID: `item:exam-midterm_2023-11-w3-higher-order-patterns` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `exam-midterm_2023-11-w3-higher-order-patterns` + Bucket: `recommended` | Type: `source_exam` + Preview: You need to write a function called sort_list that accepts a list of integers. The function should return a new list, in which the elements are sorted from highest to lowest based on their absolute values. + +### Higher-Order Patterns + +- Snippet ID: `item:exam-midterm_2023-13-w3-higher-order-patterns` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `exam-midterm_2023-13-w3-higher-order-patterns` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose you have the following functions, one to elevates a number to square and the second elevates to cube: def square(n): return (n**2) def cube(n): return (n**3) You want to apply both functions to the elements in a… + +### Higher-Order Patterns + +- Snippet ID: `item:exam-midterm_2024-19-w3-higher-order-patterns` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `exam-midterm_2024-19-w3-higher-order-patterns` + Bucket: `recommended` | Type: `source_exam` + Preview: You have four different blocks of code. Three of them return the same list, one of them returns something different. Which block of code prints something different than the other blocks print? + +### Higher-Order Patterns + +- Snippet ID: `item:exam-trial_midterm-17-w3-higher-order-patterns` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `exam-trial_midterm-17-w3-higher-order-patterns` + Bucket: `recommended` | Type: `source_exam` + Preview: You have four different blocks of code. Three of them return the same list, one of them returns something different. Which block of code prints something different than the other blocks print? + +### Higher-Order Patterns + +- Snippet ID: `item:ks-58858d6d96` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `ks-58858d6d96` + Bucket: `recommended` | Type: `source_lecture` + Preview: Lambda functions Anonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max. Lambda basics add_two = lambda x, y: x +… + +### Higher-Order Patterns + +- Snippet ID: `item:ks-994a4083e3` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `ks-994a4083e3` + Bucket: `recommended` | Type: `source_lecture` + Preview: function_factories def function_factory(increment): def adder(n1): return n1 + increment return adder add4 = function_factory(4) add5 = function_factory (5) print(add4(3)) print(add5(3)) + +### Higher-Order Patterns + +- Snippet ID: `item:ks-f069ee6a0b` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `1` + +- `ks-f069ee6a0b` + Bucket: `recommended` | Type: `source_lecture` + Preview: Nested functions and function factories Functions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory… + +### Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + +- Snippet ID: `subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core` +- Topic: Higher-Order Patterns +- Card ID: `w3-higher-order-patterns` +- Piece count: `11` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: Function factory def function_factory(increment): def adder(n1): return n1 + increment return adder add4 = function_factory(4) add5 = function_factory(5) print(add4(3)) # 7 print(add5(3)) # 8 Functions can be defined in… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: Lambda basics add_two = lambda x, y: x + y print(add_two(1, 2)) # 3 # Equivalent to: def add_two(x, y): return x + y Anonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: map() with lambda l1 = [1, 2, 3, 4, 5, 6] print(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12] # Need list() to convert map object to list Anonymous one-line functions. Syntax: lambda params: expression. Equival… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: `map` can combine multiple iterables left = [1, 2, 3] right = [10, 20, 30] print(list(map(lambda x, y: x + y, left, right))) A lambda can take multiple parameters, and `map(...)` then feeds one element from each iterabl… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: sorted_key l1 = ['a', 'B', 'c'] print(sorted(l1)) +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: sorted_key l1 = ['ad', 'dc', 'ce'] print(sorted(l1)) +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: sorted_builtins l1 = ['aaa', 'bb', 'c'] print(sorted(l1)) +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: sorted_builtins l1 = ['aaa', 'bb', 'c'] print(sorted(l1, key=len)) +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: Functions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern). +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: Anonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...) + Preview: `lambda x: expr` names one element at a time, and `map(f, seq)` returns a lazy iterable. Wrap it in `list(...)` when you need to inspect or print the mapped results. + +### Return Behavior + +- Snippet ID: `item:exam-Resit 22/23-3-w3-return-behavior` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `exam-Resit 22/23-3-w3-return-behavior` + Bucket: `recommended` | Type: `source_exam` + Preview: What will be printed by the following code segment? a b c d b The function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list… + +### Return Behavior + +- Snippet ID: `item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior` + Bucket: `recommended` | Type: `source_exam` + Preview: What is the output of the following code segment? a b c d a The types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict. + +### Return Behavior + +- Snippet ID: `item:exam-extra_practice-7-w3-return-behavior` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `exam-extra_practice-7-w3-return-behavior` + Bucket: `recommended` | Type: `source_exam` + Preview: def multiply(num1, num2): global result result = num1 * num2 print(multiply(2, 3)) print(result) a b c d b multiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global res… + +### Return Behavior + +- Snippet ID: `item:exam-extra_practice-9-w3-return-behavior` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `exam-extra_practice-9-w3-return-behavior` + Bucket: `recommended` | Type: `source_exam` + Preview: Assume sum_even_in_list(l1) filters non-integers and sums even integers. You want sum_even_integers that accepts a flexible number of arguments. For example: sum_even_integers(1,'2', 3.0, 4) should return 4. Which of th… + +### Return Behavior + +- Snippet ID: `item:exam-midterm_2024-1-w3-return-behavior` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `exam-midterm_2024-1-w3-return-behavior` + Bucket: `recommended` | Type: `source_exam` + Preview: Consider the following code snippet: a = True b = False c = True d = False if not (a or b) and (c or d): print("True") else: print("False") What will be printed by the code? A True B False C The code will result in an e… + +### Return Behavior + +- Snippet ID: `item:exam-trial-final-exam-py22-3-w3-return-behavior` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `exam-trial-final-exam-py22-3-w3-return-behavior` + Bucket: `recommended` | Type: `source_exam` + Preview: What will be returned by the following code segment? a b c d a The function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None. + +### Return Behavior + +- Snippet ID: `item:kp-manual-mutating-methods-none-d1` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `kp-manual-mutating-methods-none-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Common `None` traps Code | What comes back function with no `return` hit | None l1.sort() | None l1.append(x) | None s.upper() | new string + +### Return Behavior + +- Snippet ID: `item:ks-00b2983ca8` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `ks-00b2983ca8` + Bucket: `recommended` | Type: `source_lecture` + Preview: Return statement Returns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in h… + +### Return Behavior + +- Snippet ID: `item:ks-14515a5856` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `ks-14515a5856` + Bucket: `recommended` | Type: `source_lecture` + Preview: Implicit return — None If a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None: Implicit None… + +### Return Behavior + +- Snippet ID: `item:ks-d1a2d7739d` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `ks-d1a2d7739d` + Bucket: `recommended` | Type: `source_lecture` + Preview: Single-element tuple (1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x 1-element tuple gotcha t1 = (1) print(type(t1) == tuple) # False print(typ… + +### Return Behavior + +- Snippet ID: `item:ks-db93da9e3e` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `1` + +- `ks-db93da9e3e` + Bucket: `recommended` | Type: `source_lecture` + Preview: pass keyword Does nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this. pass as stub def add… + +### return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + +- Snippet ID: `subtopic:w3-return-behavior:w3-return-behavior-core` +- Topic: Return Behavior +- Card ID: `w3-return-behavior` +- Piece count: `13` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Returning a tuple (multiple values) def powers(n1): return n1 ** 2, n1 ** 3 # returns a tuple power2, power3 = powers(3) print(power2, power3) # 9 27 Returns a value to the caller. If you don't capture the return value… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Implicit None return def adder(n1, n2): if type(n1) == type(n2) == int: total = n1 + n2 return total a = adder('1', 2) # Returns None (no return hit) print(a) # None If a function reaches the end without a return statem… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: 1-element tuple gotcha t1 = (1) print(type(t1) == tuple) # False print(type(t1) == int) # True t1 = (1,) # correct 1-element tuple t1 = 1, # also correct x, y = y, x # swap using tuple unpacking (1) is NOT a tuple — it'… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Mutating method returns `None` l1 = [3, 1, 2] result = l1.sort() print(result) print(l1) A missing `return` is not the only source of `None`: mutating methods such as `sort()` often change the object in place and return… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Function return value and trace def adder(n1, n2): return n1 + n2 a = adder(1,2) print(a) Trace the returned value, not just what gets printed while the function runs. +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Computed a local variable but forgot to return it def adder(n1, n2): total = n1 + n2 a = adder(1, 2) print(a) Trace the returned value, not just what gets printed while the function runs. +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: A tuple return stays one tuple value def powers(n1): return n1 ** 2, n1 ** 3 a = powers(3) print(a) Trace the returned value, not just what gets printed while the function runs. +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Unpack a tuple return into multiple names def powers(n1): return n1 ** 2, n1 ** 3 power2, power3 = powers(3) print(power2, power3) Trace the returned value, not just what gets printed while the function runs. +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Returns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: If a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None: +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: (1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: Does nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this. +- `kp-manual-mutating-methods-none` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: return, Implicit None, Multiple Returns, pass, and Single-Element Tuples + Preview: A missing `return` is not the only source of `None`: many mutating methods also return `None`. Keep the mutated object, not the method call result. + +### Global vs Local Names and Scope Errors + +- Snippet ID: `subtopic:w3-scope:w3-scope-core` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `4` + +- `manual-scope-global-change` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Global vs Local Names and Scope Errors + Preview: Use `global` to rebind a global name n1 = 1 def changer(): global n1 n1 = n1 + 1 changer() print(n1) With `global n1`, the assignment updates the global name instead of creating a local one. 2 +- `manual-scope-local-name` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Global vs Local Names and Scope Errors + Preview: Local names disappear after the call def adder(n1, n2): return n1 + n2 print(adder(1, 2)) print(n1) After the function call, `n1` and `n2` no longer exist outside the function body. Return the value if the caller needs… +- `manual-scope-rebind-parameter` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Global vs Local Names and Scope Errors + Preview: Rebinding a parameter does not change the caller's name def changer(n1): n1 = n1 + 1 return n1 a = 1 a = changer(a) print(a) The function works with its local parameter; the caller changes only because the returned valu… +- `manual-scope-unbound` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Global vs Local Names and Scope Errors + Preview: Assignment makes the name local b = 1 def main(a): b = b return a print(main(1)) Because `b` is assigned inside `main`, Python treats it as local before the `b = b` line runs. UnboundLocalError + +### Scope + +- Snippet ID: `item:exam-Resit 22/23-2-w3-scope` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-Resit 22/23-2-w3-scope` + Bucket: `recommended` | Type: `source_exam` + Preview: Executing the following program will produce an error. Why? a b c d a The variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope w… + +### Scope + +- Snippet ID: `item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-Test Resit - Introduction to Python - 22/23-2-w3-scope` + Bucket: `recommended` | Type: `source_exam` + Preview: Executing the following program will produce an error. Why? a b c d d The variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the functi… + +### Scope + +- Snippet ID: `item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-Trial final - Introduction to Python - 22/23-2-w3-scope` + Bucket: `recommended` | Type: `source_exam` + Preview: Calling the function func_1() will produce an error. Which line of the following code segment produces the error? a b c d a var_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthe… + +### Scope + +- Snippet ID: `item:exam-extra_practice-2-w3-scope` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-extra_practice-2-w3-scope` + Bucket: `recommended` | Type: `source_exam` + Preview: val = 2 def func(): val = 3 print(val) func() print(val) Which of the following code snippets produces the same output as the above code snippet? a b c d c Original output: 3, 2. Option a: UnboundLocalError (val1 used b… + +### Scope + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-15-w2-conditions` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-15-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: Executing the following program will produce an error. Why? A B C D A The variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope. + +### Scope + +- Snippet ID: `item:exam-midterm_2023-3-w3-scope` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-midterm_2023-3-w3-scope` + Bucket: `recommended` | Type: `source_exam` + Preview: Which other program will give the same output as the following code snippet? + +### Scope + +- Snippet ID: `item:exam-midterm_2024-5-w3-scope` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-midterm_2024-5-w3-scope` + Bucket: `recommended` | Type: `source_exam` + Preview: Which other program will produce the same output as the following code snippet? + +### Scope + +- Snippet ID: `item:exam-trial-final-exam-py22-2-w3-scope` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `exam-trial-final-exam-py22-2-w3-scope` + Bucket: `recommended` | Type: `source_exam` + Preview: Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why? a b c d b The global variable 'a' is accessible inside the inner function without error. The code evaluates… + +### Scope + +- Snippet ID: `item:kp-manual-scope-global` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `kp-manual-scope-global` + Bucket: `keyPoints` | Type: `key_point` + Preview: Use `global x` only when the function should rebind the global name `x`; mutating an object passed in as an argument does not require `global`. + +### Scope + +- Snippet ID: `item:kp-manual-scope-local` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `kp-manual-scope-local` + Bucket: `keyPoints` | Type: `key_point` + Preview: Names assigned inside a function are local by default, including parameter names. + +### Scope + +- Snippet ID: `item:kp-manual-scope-return-outside` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `kp-manual-scope-return-outside` + Bucket: `keyPoints` | Type: `key_point` + Preview: A local variable disappears after the function ends. If you need that value outside the function, return it and assign the result in the caller. + +### Scope + +- Snippet ID: `item:kp-manual-scope-unbound` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `kp-manual-scope-unbound` + Bucket: `keyPoints` | Type: `key_point` + Preview: If a function assigns to a name anywhere, Python treats that name as local throughout that function unless `global` or `nonlocal` says otherwise. + +### Scope + +- Snippet ID: `item:ks-2a6510492d` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `ks-2a6510492d` + Bucket: `recommended` | Type: `source_lecture` + Preview: Global and local scope Local names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-na… + +### Scope + +- Snippet ID: `item:manual-global` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `manual-global` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: When do you need `global`? Use `global name` only when the function should rebind a global variable; simple reads of a global name do not need it. n1 = 1 def changer(): global n1 n1 = n1 + 1 + +### Scope + +- Snippet ID: `item:manual-local-name` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `manual-local-name` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Why does `print(n1)` fail outside `def adder(n1, n2): ...`? Parameter names are local to the function body, so they do not exist in the global scope after the call finishes. def adder(n1, n2): return n1 + n2 adder(1, 2)… + +### Scope + +- Snippet ID: `item:manual-unboundlocal` +- Topic: Scope +- Card ID: `w3-scope` +- Piece count: `1` + +- `manual-unboundlocal` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Why can assigning to a name inside a function cause `UnboundLocalError`? If a function assigns to a name anywhere in its body, Python treats that name as local throughout the function unless you declare it `global` or `… + +## Week 4 + +Snippet families in this group: **47** + +### Error Handling + +- Snippet ID: `item:ks-2c73fabc68` +- Topic: Error Handling +- Card ID: `w4-error-handling` +- Piece count: `1` + +- `ks-2c73fabc68` + Bucket: `recommended` | Type: `source_lecture` + Preview: Error Handling: try-except The try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing. Handling a ValueError s = 'abc' try: idx = s.index('z') exc… + +### Error Handling + +- Snippet ID: `item:ks-40d373c410` +- Topic: Error Handling +- Card ID: `w4-error-handling` +- Piece count: `1` + +- `ks-40d373c410` + Bucket: `recommended` | Type: `source_lecture` + Preview: The raise Keyword You can use 'raise' to manually trigger an exception when a specific condition occurs. Raising an error def check_positive(n): if n < 0: raise ValueError('Number must be positive') return n + +### try/except and raise + +- Snippet ID: `subtopic:w4-error-handling:w4-error-handling-core` +- Topic: Error Handling +- Card ID: `w4-error-handling` +- Piece count: `7` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: try/except and raise + Preview: Handling a ValueError s = 'abc' try: idx = s.index('z') except ValueError: idx = -1 The try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing. +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: try/except and raise + Preview: Raising an error def check_positive(n): if n < 0: raise ValueError('Number must be positive') return n You can use 'raise' to manually trigger an exception when a specific condition occurs. +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: try/except and raise + Preview: def my_find(s,needle): def my_find(s,needle): if (result := s.find(needle)) == -1: raise ValueError("substring not found") return result s1 ='abcdefghabcdefgh' print(my_find(s1, 'e')) print(my_find(s1, 'i')) Trace the r… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: try/except and raise + Preview: def my_index(s,needle): def my_index(s,needle): try: result = s.index(needle) except: result = -1 return result s1 ='abcdefghabcdefgh' print(my_index(s1, 'e')) print(my_index(s1, 'i')) Trace the returned value, not just… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: try/except and raise + Preview: The try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: try/except and raise + Preview: You can use 'raise' to manually trigger an exception when a specific condition occurs. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: try/except and raise + Preview: Catch the specific exception you expect when you know the failure mode. `except ValueError` documents the substring-missing case more clearly than a bare `except:`. + +### Class Definition, __init__, self, and Attribute Basics + +- Snippet ID: `subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `16` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Defining a simple class class Car: def __init__(self, color): self.color = color A class defines methods and attribute layout; `__init__` runs when you create an object and stores instance data on `self`. +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Using self to access attributes class Dog: def __init__(self, name): self.name = name def bark(self): return f'{self.name} says woof!' `self` refers to the current instance, so instance methods read and write data throu… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Shared class attribute class Counter: count = 0 def __init__(self): Counter.count += 1 `self.x` is per object; a class attribute is shared until an instance shadows it with its own value. +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: `self` is passed automatically in method calls class Clock: def set_hour(self, hour): self.hour = hour c = Clock() c.set_hour(9) # c.set_hour(c, 9) # wrong: passes one argument too many Writing `obj.method(x)` already p… +- `manual-oop-attrs` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Class attribute vs instance attribute class Rectangle: units = 'cm' def __init__(self, width): self.width = width r1 = Rectangle(3) r2 = Rectangle(5) r2.units = 'm' print(r1.units, r2.units) `self.width` is per object;… +- `manual-oop-compare-none-case` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Return `None` when neither object clearly wins class Book: def __init__(self, title, scores): self.title = title self.scores = scores def average(self): return sum(self.scores) / len(self.scores) def winner_against(self… +- `manual-oop-constructor-defaults` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Constructor defaults belong in `__init__` parameters class Vehicle: def __init__(self, name, mode="land"): self.name = name self.mode = mode car = Vehicle("Mazda") print(car.name, car.mode) Default constructor arguments… +- `manual-oop-init-defaults` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Safe default state in `__init__` class Book: def __init__(self, title, review_scores=None): self.title = title self.review_scores = [] if review_scores is None else review_scores Constructor defaults can make arguments… +- `manual-oop-state-compare` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Trace `self` state across multiple method calls class Book: def __init__(self, title): self.title = title self.scores = [] def add_review(self, score): self.scores.append(score) def average(self): return sum(self.scores… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: A class defines methods and attribute layout; `__init__` runs when you create an object and stores instance data on `self`. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: `self` refers to the current instance, so instance methods read and write data through `self.attr`. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: `self.x` is per object; a class attribute is shared until an instance shadows it with its own value. +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Method calls pass `self` automatically: `obj.set_date(x)` is correct; `obj.set_date(obj, x)` passes one argument too many. +- `kp-manual-init-defaults` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Constructor defaults can make arguments optional, but mutable per-instance state should start from `None` and be created inside `__init__`. +- `kp-manual-oop-compare` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins. +- `kp-manual-self-attr` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Class Definition, __init__, self, and Attribute Basics + Preview: Use `self.attr = ...` to store per-object state. A bare assignment like `attr = ...` inside a method only creates or updates a local variable. + +### OOP Fundamentals + +- Snippet ID: `item:cs-0d319e4faf` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `cs-0d319e4faf` + Bucket: `recommended` | Type: `source_notebook` + Preview: class Rectangle: class Rectangle: total_size = 0 def __init__(self, length, width=1): self.length = length self.width = width Rectangle.total_size += self.length * self.width print(f'{self.length} by {self.width} create… + +### OOP Fundamentals + +- Snippet ID: `item:cs-30e53467b8` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `cs-30e53467b8` + Bucket: `additional` | Type: `source_notebook` + Preview: class Rectangle: class Rectangle: total_size = 0 def __init__(self, length, width=1): self.length = length self.width = width Rectangle.total_size += self.length * self.width print(f'rectangle {self.length} by {self.wid… + +### OOP Fundamentals + +- Snippet ID: `item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `exam-Test Exam 07-06-22-1-w4-oop-fundamentals` + Bucket: `recommended` | Type: `source_exam` + Preview: Given the class definition above, trying to execute the following two code lines will result in a Python error. my_flight = Flight("KLM", "Amsterdam", "Paris") # Code line 1 my_flight.set_date(my_flight, "29-02-2022") #… + +### OOP Fundamentals + +- Snippet ID: `item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `exam-Test Exam 07-06-22-2-w4-oop-fundamentals` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is high… + +### OOP Fundamentals + +- Snippet ID: `item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals` + Bucket: `recommended` | Type: `source_exam` + Preview: You'd like to define a class called Vehicle. It should have two attributes: "name" and "mode", which you want to be initialized at the time of object construction. The "name" attribute can be any string, and it must be… + +### OOP Fundamentals + +- Snippet ID: `item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals` + Bucket: `recommended` | Type: `source_exam` + Preview: Take a look at the following class definition. Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book("The Lightning Thief", "Rick Riordan") book_1.add_review(5) book_1… + +### OOP Fundamentals + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures` + Bucket: `recommended` | Type: `source_exam` + Preview: You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the obje… + +### OOP Fundamentals + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book("The Lightning Thief", "Rick Riordan"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What wi… + +### OOP Fundamentals + +- Snippet ID: `item:kp-manual-init-defaults-d1` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `kp-manual-init-defaults-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Optional constructor argument class Vehicle: def __init__(self, name, mode='land'): self.name = name self.mode = mode + +### OOP Fundamentals + +- Snippet ID: `item:kp-manual-init-defaults-d2` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `kp-manual-init-defaults-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Fresh list per object class Book: def __init__(self, title, review_scores=None): self.title = title self.review_scores = [] if review_scores is None else review_scores + +### OOP Fundamentals + +- Snippet ID: `item:kp-manual-oop-compare-d1` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `kp-manual-oop-compare-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Comparison method template Case | Return self score > other score | winner based on `self` self score < other score | winner based on `other` tie / no clear winner | explicit fallback such as `None` + +### OOP Fundamentals + +- Snippet ID: `item:kp-manual-self-attr-d1` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `kp-manual-self-attr-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Store state on `self`, not in a local class Counter: def __init__(self): self.count = 0 def bump(self): count = self.count + 1 self.count = count + +### OOP Fundamentals + +- Snippet ID: `item:ks-06b21ad349` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `ks-06b21ad349` + Bucket: `recommended` | Type: `source_lecture` + Preview: Class Definition and __init__ A class is a blueprint. The __init__ method is the constructor called automatically when a new object is created to initialize attributes. Defining a simple class class Car: def __init__(se… + +### OOP Fundamentals + +- Snippet ID: `item:ks-5cbba26b09` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `ks-5cbba26b09` + Bucket: `recommended` | Type: `source_lecture` + Preview: Class vs Instance Attributes Instance attributes (self.x) are unique to each object. Class attributes are defined outside methods and shared by all instances of the class. Shared class attribute class Counter: count = 0… + +### OOP Fundamentals + +- Snippet ID: `item:ks-9e278d1ee6` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `ks-9e278d1ee6` + Bucket: `recommended` | Type: `source_lecture` + Preview: The self Parameter In class methods, 'self' refers to the specific instance of the object. It must be the first parameter of any instance method. Using self to access attributes class Dog: def __init__(self, name): self… + +### OOP Fundamentals + +- Snippet ID: `item:manual-init-default` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `manual-init-default` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do default values in `__init__` make constructor arguments optional? A default like `vehicle_mode='land'` can be omitted when the object is created, but the instance still receives that attribute value. class Vehicl… + +### OOP Fundamentals + +- Snippet ID: `item:manual-method-call` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `manual-method-call` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Why does `obj.set_date(obj, x)` pass too many arguments? When you call a method on an object, Python passes the object as `self` automatically. Writing it again adds one argument too many. obj.set_date(x) # correct obj.… + +### OOP Fundamentals + +- Snippet ID: `item:manual-self` +- Topic: OOP Fundamentals +- Card ID: `w4-oop-fundamentals` +- Piece count: `1` + +- `manual-self` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Why is `self` the first parameter of an instance method? `self` is the current object, so the method can read and update that object's attributes. class Flight: def set_date(self, date): self.date = date + +### f-strings Basics, Formatting, and Debug Form + +- Snippet ID: `subtopic:w4-string-formatting:w4-string-formatting-core` +- Topic: String Formatting +- Card ID: `w4-string-formatting` +- Piece count: `10` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Simple f-string name = 'Jan' print(f'{name} studies Python.') # 'Jan studies Python.' F-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional con… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Debug shortcut val = 10 print(f'{val=}') # 'val=10' Using f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value. +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Zero-padding an integer num = 7 print(f'{num:03d}') # '007' You can specify formatting after a colon, such as padding numbers with zeros. +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Using `.format(...)` with placeholders name = 'Jan' score = 7 print('Student {} scored {:03d}'.format(name, score)) The official resit material still uses `.format(...)`, so it is worth recognizing positional placeholde… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Build formatted output with custom separators cities = ['Amsterdam', 'Utrecht', 'Leiden'] text = ', '.join(cities[:-1]) + ', and ' + cities[-1] print(f'Visited: {text}') print('Average: {:.1f}'.format(7.25)) When the ou… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: F-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Using f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: You can specify formatting after a colon, such as padding numbers with zeros. +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Official assessments also use `.format(...)` placeholders. The same width and zero-padding ideas still apply there, for example `'{:04d}'.format(n)`. +- `kp-5` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: f-strings Basics, Formatting, and Debug Form + Preview: Use f-strings for direct interpolation and `.format(...)` when the template string already exists; both support width, alignment, and precision specs such as `{:03d}` and `{:.2f}`. + +### String Formatting + +- Snippet ID: `item:ks-72dda5450c` +- Topic: String Formatting +- Card ID: `w4-string-formatting` +- Piece count: `1` + +- `ks-72dda5450c` + Bucket: `recommended` | Type: `source_lecture` + Preview: F-strings Basics F-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation. Simple f-string name = 'Jan' print(f'{name} studies Pytho… + +### String Formatting + +- Snippet ID: `item:ks-acb7f400b2` +- Topic: String Formatting +- Card ID: `w4-string-formatting` +- Piece count: `1` + +- `ks-acb7f400b2` + Bucket: `recommended` | Type: `source_lecture` + Preview: F-strings Formatting You can specify formatting after a colon, such as padding numbers with zeros. Zero-padding an integer num = 7 print(f'{num:03d}') # '007' + +### String Formatting + +- Snippet ID: `item:ks-ea5a4acb43` +- Topic: String Formatting +- Card ID: `w4-string-formatting` +- Piece count: `1` + +- `ks-ea5a4acb43` + Bucket: `recommended` | Type: `source_lecture` + Preview: F-strings Debugging Using f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value. Debug shortcut val = 10 print(f'{val=}') # 'val=10' + +### Quotes, Escape Characters, and Immutability + +- Snippet ID: `subtopic:w4-string-fundamentals:w4-string-fundamentals-core` +- Topic: String Fundamentals +- Card ID: `w4-string-fundamentals` +- Piece count: `8` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: Methods return new strings s1 = 'abcd' s1.capitalize() # Returns 'Abcd' print(s1) # Still prints 'abcd' Strings are immutable: methods like `.upper()` and `.replace()` return a new string, so assign the result back if y… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: Newlines and tabs print('Line 1\nLine 2\tTabbed') print("It\'s a string") Escape sequences: `\n` newline, `\t` tab, and `\'` or `\"` for literal quotes. +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: Filter uppercase letters with a helper function def my_isupper(s1): for el in s1: if el not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": return False return True x = "Harry Potter and the Philosopher's Stone" y = '' for i in x: if… +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: `len(s)` counts characters a = 'adbc' print(len(a)) Count every character in the string, including letters, spaces, and punctuation if they are present. 4 +- `manual-string-literals-example` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: Quotes and newline escapes print("it's") print('He said "hi"') print("Line 1\nLine 2") Use matching quotes or escape the inner quote; `\n` inserts a newline. it's He said "hi" Line 1 Line 2 +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: Strings are immutable: methods like `.upper()` and `.replace()` return a new string, so assign the result back if you want the change to stick. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: Escape sequences: `\n` newline, `\t` tab, and `\'` or `\"` for literal quotes. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Quotes, Escape Characters, and Immutability + Preview: Strings are immutable: `s[0] = 'A'` fails, so rebuild or rebind, for example `s = 'A' + s[1:]`. + +### String Fundamentals + +- Snippet ID: `item:cs-14245b8c1f` +- Topic: String Fundamentals +- Card ID: `w4-string-fundamentals` +- Piece count: `1` + +- `cs-14245b8c1f` + Bucket: `recommended` | Type: `source_notebook` + Preview: def my_isupper(s1): def my_isupper(s1): for el in s1: if el not in "ABCDEFGHIJKLMNOPQRSTUVWXYZ": return False return True x = "Harry Potter and the Philosopher's Stone" y = '' for i in x: if my_isupper(i): y += i print(… + +### String Fundamentals + +- Snippet ID: `item:cs-e7bc165499` +- Topic: String Fundamentals +- Card ID: `w4-string-fundamentals` +- Piece count: `1` + +- `cs-e7bc165499` + Bucket: `recommended` | Type: `source_notebook` + Preview: def main(a, b): def main(a, b): return f'''The first number is: {a:04d} The second number is: {b:04d} The product is: {a * b:04d}''' print(main(7,13)) The first number is: 0007 The second number is: 0013 The product is:… + +### String Fundamentals + +- Snippet ID: `item:ks-309158a68c` +- Topic: String Fundamentals +- Card ID: `w4-string-fundamentals` +- Piece count: `1` + +- `ks-309158a68c` + Bucket: `recommended` | Type: `source_lecture` + Preview: Escape Characters Special characters like newlines (\n), tabs (\t), or literal quotes can be included using the backslash (\). Newlines and tabs print('Line 1\nLine 2\tTabbed') print("It\'s a string") + +### String Fundamentals + +- Snippet ID: `item:ks-b734a22f46` +- Topic: String Fundamentals +- Card ID: `w4-string-fundamentals` +- Piece count: `1` + +- `ks-b734a22f46` + Bucket: `recommended` | Type: `source_lecture` + Preview: String Immutability Strings in Python are immutable, meaning they cannot be changed in place. Methods like upper() or replace() return a new string object rather than modifying the original. Attempting to change a strin… + +### String Fundamentals + +- Snippet ID: `item:manual-string-escapes` +- Topic: String Fundamentals +- Card ID: `w4-string-fundamentals` +- Piece count: `1` + +- `manual-string-escapes` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do you include quotes or a newline inside a string literal? Pick the other quote style or escape the inner quote; use `\n` for a newline. print("it's") print('He said "hi"') print("Line 1\nLine 2") + +### String Fundamentals + +- Snippet ID: `item:manual-string-immutability` +- Topic: String Fundamentals +- Card ID: `w4-string-fundamentals` +- Piece count: `1` + +- `manual-string-immutability` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Why does `s[0] = 'A'` fail? Strings are immutable, so you must build a new string such as `s = 'A' + s[1:]` instead of assigning by index. s = 'abcd' s = 'A' + s[1:] + +### Slicing with Step, Search, replace, join, strip, and the string Module + +- Snippet ID: `subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `23` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Behavior when substring is missing s = 'abc' print(s.find('z')) # -1 # print(s.index('z')) # Raises ValueError Both find() and index() search for a substring. The key difference is that find() returns -1 if the substrin… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Slicing examples s = '01234567' print(s[::4]) # '04' print(s[::-2]) # '7531' Slicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string. +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Joining a list into a string words = ['a', 'b', 'c'] print('-'.join(words)) # 'a-b-c' print(''.join(words)) # 'abc' The join() method takes an iterable (like a list) and concatenates its elements using the string it is… +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Limiting replacements s = 'aaaa' print(s.replace('a', 'b', 2)) # 'bbaa' Replaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements. +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Importing string constants import string print(string.ascii_lowercase) # 'abcdef...' print(string.digits) # '0123456789' The 'string' module provides pre-defined constants like all lowercase letters, digits, and punctua… +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Stripping whitespace and characters s = ' abc ' print(s.strip()) # 'abc' s2 = 'eeabcdee' print(s2.strip('e')) # 'abcd' strip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sid… +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: s1 = 'abcdefghabcdefgh' s1 = 'abcdefghabcdefgh' print(s1.find('i')) print(s1[s1.find('i')]) print(s1.index('i')) +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: s1 = 'abcdefghabcdefgh' s1 = 'abcdefghabcdefgh' print(s1.find('e')) print(s1.index('e', 5)) print(s1.find('e', 5, 10)) print(s1.index('e', 5, 13)) print(s1.find('ef')) print(s1.index('q')) +- `manual-string-format-method` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Build strings with `.format(...)` template = "{} scored {} points" print(template.format("Ada", 9)) Use `.format(...)` on the template string, and remember it returns a new string instead of changing the original text i… +- `manual-string-indexing-reference` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Indexing, negative indices, and slices s = 'python' print(s[0], s[-1]) print(s[1:4]) print(s[::2]) print(s[::-1]) This compact reference covers the most repeated string-selection patterns: direct indexing, negative inde… +- `manual-string-islower-method` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Check lowercase letters with `.islower()` print("amsterdam".islower()) print("Amsterdam".islower()) print("123".islower()) `.islower()` only returns `True` when the string contains at least one cased character and all c… +- `manual-string-output-construction` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Join values into exam-style output text names = ['Ada', 'Bob', 'Cleo'] body = ', '.join(names[:-1]) print(f'{body}, and {names[-1]}') print('{:.2f}'.format(3.5)) Use `join` for the repeated separator, then add the custo… +- `manual-string-repetition` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Repeat text with string multiplication print(3 * "ha") print("ab" * 2) Both `n * text` and `text * n` repeat the string `n` times, which is a common concise exam pattern. hahaha abab +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Both find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Slicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: The join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator. +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Replaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements. +- `kp-5` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: The 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation. +- `kp-6` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: strip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively. +- `kp-7` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Pattern to remember: `find` returns `-1`; `index` raises `ValueError` if the substring is missing. +- `kp-8` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Indexing and slicing are exam staples: `s[i]` gets one character, `s[-1]` starts from the end, and slices use an exclusive stop with optional step values such as `s[1:5]`, `s[::2]`, and `s[::-1]`. +- `kp-9` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: Boolean string predicates answer slightly different questions: `.islower()` and `.isupper()` need at least one cased character, `.isdigit()` checks digits only, and spaces or punctuation usually make the result `False`. +- `kp-manual-string-method-results` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Slicing with Step, Search, replace, join, strip, and the string Module + Preview: String methods like `replace`, `capitalize`, `split`, and `join` return new values; the original string stays unchanged unless you assign the result. + +### String Operations and Methods + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-22-w2-conditions` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-22-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: Which script, using the count string method, would print the value 1 for x = 'Amsterdam'? A B C D B The count() method is a string method, not a standalone function. It is called using the dot notation on a string objec… + +### String Operations and Methods + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-4-w2-conditions` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-4-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes? A B C D A Strings in Python are immutable. The .replace() method returns a new string but does not… + +### String Operations and Methods + +- Snippet ID: `item:kp-5-d1` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `5` + +- `kp-5-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Importing string constants import string print(string.ascii_lowercase) # 'abcdef...' print(string.digits) # '0123456789' +- `kp-5-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Formatting patterns at a glance Goal | f-string | .format(...) insert a value | f'{name}' | '{}'.format(name) zero-pad an int | f'{n:03d}' | '{:03d}'.format(n) 2 decimals | f'{x:.2f}' | '{:.2f}'.format(x) +- `kp-5-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Filter by condition df[df['Weight'] > 60] df.loc[df.Age < 155] +- `kp-5-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Formatting with map df['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g') +- `kp-5-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Equivalent logic using map/filter l2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4]))) + +### String Operations and Methods + +- Snippet ID: `item:kp-8-d1` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `2` + +- `kp-8-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Indexing and slicing quick rules Pattern | Meaning | Trap s[0], s[-1] | first / last character | single-index access can raise IndexError s[a:b] | start inclusive, stop exclusive | safe even if b is past the end s[::2]… +- `kp-8-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Divide by index plus offset res = [val // (i + 6) for i, val in enumerate([46, 48])] + +### String Operations and Methods + +- Snippet ID: `item:kp-9-d1` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `kp-9-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Predicate truth table Input | Check | Result 'abc'.islower() | all cased chars lowercase | True 'Abc'.islower() | contains uppercase | False '123'.isdigit() | all chars are digits | True 'abc!'.islower() | punctuation i… + +### String Operations and Methods + +- Snippet ID: `item:kp-manual-string-method-results-d1` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `kp-manual-string-method-results-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: replace() returns a new string number = '020-525-1400' cleaned = number.replace('-', '') print(number) # '020-525-1400' print(cleaned) # '0205251400' + +### String Operations and Methods + +- Snippet ID: `item:ks-45aead894c` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `ks-45aead894c` + Bucket: `recommended` | Type: `source_lecture` + Preview: The replace Method Replaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements. Limiting replacements s = 'aaaa' print(s.replace('a', 'b', 2)) # 'bbaa' + +### String Operations and Methods + +- Snippet ID: `item:ks-5198d93ec1` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `ks-5198d93ec1` + Bucket: `recommended` | Type: `source_lecture` + Preview: String Searching: find vs index Both find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError. Behavior when substring is m… + +### String Operations and Methods + +- Snippet ID: `item:ks-bdea67862f` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `ks-bdea67862f` + Bucket: `additional` | Type: `source_lecture` + Preview: The string Module The 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation. Importing string constants import string print(string.ascii_lowercase) # 'abcdef...' print(string… + +### String Operations and Methods + +- Snippet ID: `item:ks-cdb152720e` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `ks-cdb152720e` + Bucket: `recommended` | Type: `source_lecture` + Preview: The join Method The join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator. Joining a list into a string words = ['a', 'b', 'c'] print('-'.join(words)… + +### String Operations and Methods + +- Snippet ID: `item:ks-e4dc502d3e` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `ks-e4dc502d3e` + Bucket: `additional` | Type: `source_lecture` + Preview: String Stripping strip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively. Stripping whitespace and characters s = ' abc ' print(s.strip()) # 'abc' s2 = 'eeabcd… + +### String Operations and Methods + +- Snippet ID: `item:ks-f80f1bf556` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `ks-f80f1bf556` + Bucket: `recommended` | Type: `source_lecture` + Preview: String Slicing with Step Slicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string. Slicing examples s = '01234567' print(s[::4]) # '04' print(s[::-2]) # '7531' + +### String Operations and Methods + +- Snippet ID: `item:manual-find-vs-index` +- Topic: String Operations and Methods +- Card ID: `w4-string-operations-and-methods` +- Piece count: `1` + +- `manual-find-vs-index` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What is the difference between `s.find(x)` and `s.index(x)` when `x` is missing? `find` returns `-1`; `index` raises `ValueError`. s = 'banana' print(s.find('x')) print(s.index('x')) # ValueError + +## Week 5 + +Snippet families in this group: **55** + +### Combining Data + +- Snippet ID: `item:cs-b46633d18d` +- Topic: Combining Data +- Card ID: `w5-combining-data` +- Piece count: `1` + +- `cs-b46633d18d` + Bucket: `recommended` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd dftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} ) #print(dftax) dfprov = pd.DataFrame({'Ci… + +### Combining Data + +- Snippet ID: `item:ks-21496ff1cd` +- Topic: Combining Data +- Card ID: `w5-combining-data` +- Piece count: `1` + +- `ks-21496ff1cd` + Bucket: `recommended` | Type: `source_lecture` + Preview: Merging Database-style joins using .merge(). 'how' determines the type (left, right, inner, outer). Left join on a key df1.merge(df2, on='Town', how='left') + +### Combining Data + +- Snippet ID: `item:ks-591dd1aa33` +- Topic: Combining Data +- Card ID: `w5-combining-data` +- Piece count: `1` + +- `ks-591dd1aa33` + Bucket: `recommended` | Type: `source_lecture` + Preview: Concatenation Gluing DataFrames together using pd.concat(). Vertical stack pd.concat([df1, df2], axis=0) + +### Combining Data + +- Snippet ID: `item:ks-f1be187b50` +- Topic: Combining Data +- Card ID: `w5-combining-data` +- Piece count: `1` + +- `ks-f1be187b50` + Bucket: `recommended` | Type: `source_lecture` + Preview: Grouping The Split-Apply-Combine pattern using .groupby(). Grouped aggregation df.groupby('Nationality')['Height'].median() + +### Concatenation, Merging, and Grouping + +- Snippet ID: `subtopic:w5-combining-data:w5-combining-data-core` +- Topic: Combining Data +- Card ID: `w5-combining-data` +- Piece count: `8` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Concatenation, Merging, and Grouping + Preview: Vertical stack pd.concat([df1, df2], axis=0) Gluing DataFrames together using pd.concat(). +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Concatenation, Merging, and Grouping + Preview: Left join on a key df1.merge(df2, on='Town', how='left') Database-style joins using .merge(). 'how' determines the type (left, right, inner, outer). +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Concatenation, Merging, and Grouping + Preview: Grouped aggregation df.groupby('Nationality')['Height'].median() The Split-Apply-Combine pattern using .groupby(). +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Concatenation, Merging, and Grouping + Preview: import pandas as pd import pandas as pd dftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} ) #print(dftax) dfprov = pd.DataFrame({'Ci… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Concatenation, Merging, and Grouping + Preview: import pandas as pd import pandas as pd dftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} ) print(dftax) dfprov = pd.DataFrame({'Cit… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Concatenation, Merging, and Grouping + Preview: Gluing DataFrames together using pd.concat(). +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Concatenation, Merging, and Grouping + Preview: Database-style joins using .merge(). 'how' determines the type (left, right, inner, outer). +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Concatenation, Merging, and Grouping + Preview: The Split-Apply-Combine pattern using .groupby(). + +### head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + +- Snippet ID: `subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `14` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Summary stats print(df.describe()) Use .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics. +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Select rows/cols by name df.loc['First':'Third', ['Name', 'Weight']] Label-based selection. Slicing with .loc is inclusive of the end name. +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Select by position df.iloc[0:2, 0:1] # Rows 0,1; Col 0 Integer-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists). +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Series vs DataFrame result type(df.loc[2]) # Series type(df.loc[[2]]) # DataFrame Selecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame. +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Filter by condition df[df['Weight'] > 60] df.loc[df.Age < 155] Filtering data by passing a mask of True/False values (often created via comparisons). +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: import pandas as pd import pandas as pd d1 = [['A', 'B', 'C'],[153, 160, 150],[55, 70, 60]] df1 = pd.DataFrame (d1) df1 = df1.drop(1, axis = 0) df1 = df1.drop(1, axis = 1) print(df1) result = df1.iloc[2, 2] print(result… +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Label, mask, and step-based row selection import pandas as pd d1 = {10:['A', 'B', 'C', 'D'], 13:[153, 160, 150, 190], 12:[55, 70, 60, 80], 17:[10, 11, 12, 13]} df1 = pd.DataFrame (d1, index=[3, 2, 1, 0]) print(df1) prin… +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Valid vs invalid indexing forms df.loc[2:4, ['B']] df.iloc[1:4, [1]] df.loc[df['A'] > 0, ['B', 'C']] # invalid shortcut: # df[2, 'B'] Keep the rule simple: plain `df[...]` is not the place for a row selector plus a colu… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Use .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Label-based selection. Slicing with .loc is inclusive of the end name. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Integer-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists). +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Selecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame. +- `kp-5` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Filtering data by passing a mask of True/False values (often created via comparisons). +- `kp-6` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: head, tail, describe, loc, iloc, Result Types, and Boolean Indexing + Preview: Selection rule: plain `df[...]` handles columns or a row mask, while `.loc[row_sel, col_sel]` and `.iloc[row_sel, col_sel]` handle both axes explicitly. `df[row, col]` is not the shortcut you want. + +### Inspecting and Selecting Data + +- Snippet ID: `item:cs-3d987070d4` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `cs-3d987070d4` + Bucket: `recommended` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = [['A', 'B', 'C'],[153, 160, 150],[55, 70, 60]] df1 = pd.DataFrame (d1) df1 = df1.drop(1, axis = 0) df1 = df1.drop(1, axis = 1) print(df1) result = df1.iloc[2, 2] print(result… + +### Inspecting and Selecting Data + +- Snippet ID: `item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data` + Bucket: `recommended` | Type: `source_exam` + Preview: You have a pandas DataFrame called df that looks like this, when printed: A B C D 1 9.1 9.5 9.0 6.0 2 6.4 8.2 7.5 1.7 3 2.5 5.3 8.8 3.0 4 6.7 3.6 7.2 6.9 5 8.4 1.9 8.2 3.3 6 8.1 8.4 9.9 2.2 Suppose that you'd like to cr… + +### Inspecting and Selecting Data + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want? A B C D A Option A uses a boolean mask on… + +### Inspecting and Selecting Data + +- Snippet ID: `item:ks-0114a2cff0` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `ks-0114a2cff0` + Bucket: `recommended` | Type: `source_lecture` + Preview: Viewing Data Use .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics. Summary stats print(df.describe()) + +### Inspecting and Selecting Data + +- Snippet ID: `item:ks-57ff66f9f1` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `ks-57ff66f9f1` + Bucket: `recommended` | Type: `source_lecture` + Preview: Selection: loc Label-based selection. Slicing with .loc is inclusive of the end name. Select rows/cols by name df.loc['First':'Third', ['Name', 'Weight']] + +### Inspecting and Selecting Data + +- Snippet ID: `item:ks-99fe849762` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `ks-99fe849762` + Bucket: `recommended` | Type: `source_lecture` + Preview: Selection Result Types Selecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame. Series vs DataFrame result type(df.loc[2]) # Series type(df.loc[[2]]) # DataFrame + +### Inspecting and Selecting Data + +- Snippet ID: `item:ks-dfc064979d` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `ks-dfc064979d` + Bucket: `recommended` | Type: `source_lecture` + Preview: Selection: iloc Integer-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists). Select by position df.iloc[0:2, 0:1] # Rows 0,1; Col 0 + +### Inspecting and Selecting Data + +- Snippet ID: `item:ks-f550a3ffc7` +- Topic: Inspecting and Selecting Data +- Card ID: `w5-inspecting-and-selecting-data` +- Piece count: `1` + +- `ks-f550a3ffc7` + Bucket: `additional` | Type: `source_lecture` + Preview: Boolean Indexing Filtering data by passing a mask of True/False values (often created via comparisons). Filter by condition df[df['Weight'] > 60] df.loc[df.Age < 155] + +### Pandas Core Structures + +- Snippet ID: `item:cs-2e178eda82` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-2e178eda82` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2.loc[[1,2]] += 1 print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0 2 3 1 6 5 2 7 8 + +### Pandas Core Structures + +- Snippet ID: `item:cs-49cf15967e` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-49cf15967e` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2.A += 1 print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0 3 3 1 6 4 2 7 7 + +### Pandas Core Structures + +- Snippet ID: `item:cs-82ef14b9d5` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-82ef14b9d5` + Bucket: `recommended` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2 += 1 print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0 3 4 1 6 5 2 7 8 + +### Pandas Core Structures + +- Snippet ID: `item:cs-8bae99d6de` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-8bae99d6de` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2.A += [1, 2] print(df2) A B 0 2 3 1 5 4 2 6 7 + +### Pandas Core Structures + +- Snippet ID: `item:cs-8ec741987c` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-8ec741987c` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2 += pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]}) print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0… + +### Pandas Core Structures + +- Snippet ID: `item:cs-b069af91f4` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-b069af91f4` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2 += pd.DataFrame({'A':[2, 5, 6], 'B':[3, 4, 7]}, index=[4,5,6]) print(df2) A B 0 2 3 1 5… + +### Pandas Core Structures + +- Snippet ID: `item:cs-b3e0b57d7a` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-b3e0b57d7a` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2.A = df2.A.map(lambda x: 3 * x) print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0 6 3 1 15 4 2 18 7 + +### Pandas Core Structures + +- Snippet ID: `item:cs-c4c296595e` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-c4c296595e` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2.loc[1] += 1 print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0 2 3 1 6 5 2 6 7 + +### Pandas Core Structures + +- Snippet ID: `item:cs-cdfd529b3d` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-cdfd529b3d` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2.A += [1, 2, 3] print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0 3 3 1 7 4 2 9 7 + +### Pandas Core Structures + +- Snippet ID: `item:cs-e6b6bd65f0` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `cs-e6b6bd65f0` + Bucket: `additional` | Type: `source_notebook` + Preview: import pandas as pd import pandas as pd d1 = {'A':[2, 5, 6], 'B':[3, 4, 7]} df1 = pd.DataFrame (d1) print(df1) df2 = df1.loc[:] df2.loc[1] = df2.loc[1].map(lambda x: 3 * x) print(df2) A B 0 2 3 1 5 4 2 6 7 A B 0 2 3 1 1… + +### Pandas Core Structures + +- Snippet ID: `item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `exam-Test Exam 07-06-22-5-w5-pandas-core-structures` + Bucket: `recommended` | Type: `source_exam` + Preview: You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elem… + +### Pandas Core Structures + +- Snippet ID: `item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures` + Bucket: `recommended` | Type: `source_exam` + Preview: You have a pandas DataFrame called df. It has a column called "A" and a column called "B". Both contain numbers. You'd like to create a column called "C", which contains the sum of the numbers in columns "A" and "B". Wh… + +### Pandas Core Structures + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-5-w4-string-fundamentals` + Bucket: `recommended` | Type: `source_exam` + Preview: You have a pandas DataFrame called df with columns "A" and "B". You'd like to create a column called "C", which contains the sum of the numbers in columns "A" and "B". Which of the following code lines will achieve what… + +### Pandas Core Structures + +- Snippet ID: `item:kp-manual-df-constructor` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `kp-manual-df-constructor` + Bucket: `keyPoints` | Type: `key_point` + Preview: A `DataFrame` is a 2D table; a dict of column names to equal-length lists is the standard constructor pattern. + +### Pandas Core Structures + +- Snippet ID: `item:kp-manual-pandas-two-axis` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `kp-manual-pandas-two-axis` + Bucket: `keyPoints` | Type: `key_point` + Preview: Plain `df[...]` is for column selection or a row mask. If you need both rows and columns, switch to `.loc[row_sel, col_sel]` or `.iloc[row_sel, col_sel]` instead of writing `df[row, col]`. + +### Pandas Core Structures + +- Snippet ID: `item:kp-manual-pandas-two-axis-d1` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `kp-manual-pandas-two-axis-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Valid vs invalid two-axis selection Form | Valid? | Use for df['A'] | yes | one column df[['A', 'B']] | yes | multiple columns df.loc[2:4, ['A']] | yes | label-based row + column selection df.iloc[1:3, [0]] | yes | posi… + +### Pandas Core Structures + +- Snippet ID: `item:kp-manual-series-default-index` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `kp-manual-series-default-index` + Bucket: `keyPoints` | Type: `key_point` + Preview: A `Series` is 1D labeled data; if you do not supply an index, pandas uses `0, 1, 2, ...`. + +### Pandas Core Structures + +- Snippet ID: `item:kp-manual-series-vs-df` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `kp-manual-series-vs-df` + Bucket: `keyPoints` | Type: `key_point` + Preview: Single-column brackets return a `Series`, while a list of column names returns a `DataFrame`: `df['A']` -> Series, `df[['A']]` -> one-column DataFrame, `df[['A', 'B']]` -> two-column DataFrame. + +### Pandas Core Structures + +- Snippet ID: `item:kp-manual-series-vs-df-d1` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `kp-manual-series-vs-df-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Column-selection shape rules Code | Returns | Why it matters df['A'] | Series | one column, one bracket pair df[['A']] | DataFrame | list of columns keeps 2D shape df[['A', 'B']] | DataFrame | multi-column subset + +### Pandas Core Structures + +- Snippet ID: `item:ks-052ed25923` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `ks-052ed25923` + Bucket: `recommended` | Type: `source_lecture` + Preview: pd.Series A one-dimensional labeled array. If no index is provided, it defaults to integers starting from 0. Creating a Series from a list import pandas as pd s1 = pd.Series([153, 160, 150], name='Length') + +### Pandas Core Structures + +- Snippet ID: `item:ks-75cf35c8b4` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `ks-75cf35c8b4` + Bucket: `recommended` | Type: `source_lecture` + Preview: DatetimeIndex A specialized index for dates. Elements have attributes like .year, .month, and .day. Filtering by month df.loc[[r for r in df.index if r.month == 4]] + +### Pandas Core Structures + +- Snippet ID: `item:ks-9a5d2c05fb` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `ks-9a5d2c05fb` + Bucket: `recommended` | Type: `source_lecture` + Preview: pd.DataFrame A two-dimensional tabular data structure. Most commonly created from a dictionary where keys are column names and values are lists. Creating from dictionary d = {'Name': ['A', 'B'], 'Weight': [55, 70]} df =… + +### Pandas Core Structures + +- Snippet ID: `item:manual-df-constructor` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `manual-df-constructor` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How do you build a `DataFrame` from a dict of column names to lists? Each key becomes a column, and each list supplies that column's values row by row. df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]}) + +### Pandas Core Structures + +- Snippet ID: `item:manual-series-index` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `manual-series-index` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What index does a `Series` get if you do not provide one explicitly? Pandas uses the default integer index `0, 1, 2, ...`. s = pd.Series([10, 20, 30]) + +### Pandas Core Structures + +- Snippet ID: `item:manual-series-vs-dataframe` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `1` + +- `manual-series-vs-dataframe` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: What does `df['A']` return versus `df[['A']]`? `df['A']` returns a `Series`; `df[['A']]` returns a one-column `DataFrame`. df['A'] df[['A']] + +### Series, DataFrame, and Creation Patterns + +- Snippet ID: `subtopic:w5-pandas-core-structures:w5-pandas-core-structures-core` +- Topic: Pandas Core Structures +- Card ID: `w5-pandas-core-structures` +- Piece count: `5` + +- `manual-pandas-df` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Series, DataFrame, and Creation Patterns + Preview: Build a `DataFrame` from a dict of columns df = pd.DataFrame({'A': [1, 2], 'B': [3, 4]}) print(df) Each dict key becomes a column and the lists provide the row values for that column. A B 0 1 3 1 2 4 +- `manual-pandas-import` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Series, DataFrame, and Creation Patterns + Preview: Import pandas with the conventional alias import pandas as pd Use the `pd` alias so constructors and methods stay short and readable during the exam. +- `manual-pandas-invalid-two-axis` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Series, DataFrame, and Creation Patterns + Preview: Use `.loc` or `.iloc` for row-plus-column selection df.loc[2:4, ['A']] df.iloc[1:3, [0]] # invalid shortcut: # df[2, 'A'] Once both a row selector and a column selector appear, switch to `.loc[...]` or `.iloc[...]` inst… +- `manual-pandas-select-shape` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Series, DataFrame, and Creation Patterns + Preview: Single brackets vs list-of-columns brackets df['A'] # Series df[['A']] # one-column DataFrame df[['A', 'B']] # two-column DataFrame Single-column brackets drop to 1D `Series` shape; wrapping the column name(s) in a list… +- `manual-pandas-series` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Series, DataFrame, and Creation Patterns + Preview: Create a `Series` from a list s = pd.Series([153, 160, 150], name='Length') print(s) Without an explicit index, pandas labels the rows `0, 1, 2, ...`. 0 153 1 160 2 150 Name: Length, dtype: int64 + +### Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + +- Snippet ID: `subtopic:w5-working-with-values:w5-working-with-values-core` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `22` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Sorting by column values df.sort_values(by='Length', ascending=False) Sort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns. +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Scalar broadcasting df['Height'] += 10 # Adds 10 to every cell in the column Applying a scalar operation (like + or *) to an entire Series or DataFrame automatically. +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Chained string operations s.str.upper().str.count('A') Accessible via .str, these allow string operations on every element of a Series. +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Filtering with isin vowels = list('aeiou') s[s.str[-1].str.lower().isin(vowels)] A vectorized version of 'in' to check if elements are within a collection. +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Formatting with map df['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g') Applies a function (often a lambda) to every element of a Series. +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Row-wise average df['Avg'] = df.apply(lambda x: x.mean(), axis=1) Applies a function along an axis (0 for columns, 1 for rows) of a DataFrame. +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Handling NaNs df.fillna('No value') # Replaces all NaNs Represented by np.nan. Use .isna() to detect and .fillna() to replace them. +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Vectorized column arithmetic df['C'] = df['A'] + df['B'] df['D'] = df['A'] - df['B'] If the exam asks for elementwise column arithmetic, direct Series expressions are usually the clearest solution and do not need `apply… +- `manual-pandas-filter-aggregate` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Filter rows, then aggregate one column result = df.loc[df['A'] > 0, 'B'].mean() print(result) A common Pandas exam pattern is: build a boolean mask first, then run `mean()`, `sum()`, or `count()` on the selected column. +- `manual-pandas-map-column-sum` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Trace `map(lambda x: x + df['B'].sum())` import pandas as pd df = pd.DataFrame({"A": [1, 2], "B": [10, 20]}) result = df["A"].map(lambda x: x + df["B"].sum()) print(result.tolist()) `df["B"].sum()` is computed from the… +- `manual-pandas-split-into-columns` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Split string data into multiple DataFrame columns import pandas as pd df = pd.DataFrame({"place": ["Amsterdam; Noord-Holland", "Utrecht; Utrecht"]}) df[["municipality", "province"]] = df["place"].str.split("; ", expand=… +- `manual-working-values-axis-apply` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: `map` vs `apply(axis=0)` vs `apply(axis=1)` s.map(lambda x: x * 2) df.apply(lambda col: col.mean(), axis=0) df.apply(lambda row: row['A'] + row['B'], axis=1) `map` is elementwise on one Series, `apply(..., axis=0)` work… +- `manual-working-values-string-vs-map` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: `.str` methods vs `map(...)` s = pd.Series(['Aap', 'Nota', 'MIES']) print(s.map(lambda x: x.lower())) print(s.str.lower()) Use `.str` for vectorized string operations; `map(...)` is useful when you need a custom per-val… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Sort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Applying a scalar operation (like + or *) to an entire Series or DataFrame automatically. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Accessible via .str, these allow string operations on every element of a Series. +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: A vectorized version of 'in' to check if elements are within a collection. +- `kp-5` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Use `Series.map(f)` for elementwise work on one Series. It expects a function, dict, or mapping-style Series; for arithmetic that already works columnwise, write the vectorized expression directly instead. +- `kp-6` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Use `DataFrame.apply(f, axis=0)` columnwise and `axis=1` rowwise. Reach for `apply` only when the function needs a whole row or column; otherwise direct column expressions are usually shorter and clearer. +- `kp-7` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Represented by np.nan. Use .isna() to detect and .fillna() to replace them. +- `kp-manual-drop-missing` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Use `.drop(...)` to remove labels and `.dropna()` to remove incomplete rows or columns; use `.fillna(...)` when you want to keep the shape and replace the missing values instead. +- `kp-manual-filter-aggregate` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply + Preview: Filter first, then aggregate the resulting Series or DataFrame: `sum()`, `mean()`, `count()`, and `sort_values(...)` are common exam follow-ups after a boolean mask. + +### Working With Values + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-7-w4-string-fundamentals` + Bucket: `recommended` | Type: `source_exam` + Preview: Which of the following code lines could NOT have created df2 from df1? A B C D A Option A would sort all 5 rows of df1 and keep columns A, C, D, resulting in a 5-row DataFrame. df2 only has 3 rows (indices 4, 3, 2). + +### Working With Values + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-8-w4-string-fundamentals` + Bucket: `recommended` | Type: `source_exam` + Preview: You have a Series s with municipality and province names separated by "; ". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want? A B… + +### Working With Values + +- Snippet ID: `item:kp-5-d2` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `kp-5-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: `map` vs direct column arithmetic Pattern | Best when | Example s.map(f) | one value in, one value out | df['W_g'] = df['Weight'].map(...) df['A'] + df['B'] | plain vectorized arithmetic | df['C'] = df['A'] + df['B'] df… + +### Working With Values + +- Snippet ID: `item:kp-manual-drop-missing-d1` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `kp-manual-drop-missing-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Dropping a column by label df = df.drop(1, axis=1) + +### Working With Values + +- Snippet ID: `item:kp-manual-drop-missing-d2` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `kp-manual-drop-missing-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Removing rows with missing values df.dropna() + +### Working With Values + +- Snippet ID: `item:kp-manual-filter-aggregate-d1` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `kp-manual-filter-aggregate-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Filter then take the mean df.loc[df['A'] > 0, 'B'].mean() + +### Working With Values + +- Snippet ID: `item:kp-manual-filter-aggregate-d2` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `kp-manual-filter-aggregate-d2` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Common follow-up operations Goal | Pattern sum selected values | df.loc[mask, 'B'].sum() mean selected values | df.loc[mask, 'B'].mean() count selected rows | df.loc[mask, 'B'].count() sort rows by a column | df.sort_va… + +### Working With Values + +- Snippet ID: `item:ks-0d2d15f8d2` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `ks-0d2d15f8d2` + Bucket: `additional` | Type: `source_lecture` + Preview: apply() Applies a function along an axis (0 for columns, 1 for rows) of a DataFrame. Row-wise average df['Avg'] = df.apply(lambda x: x.mean(), axis=1) + +### Working With Values + +- Snippet ID: `item:ks-115ab52188` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `ks-115ab52188` + Bucket: `recommended` | Type: `source_lecture` + Preview: Vectorized String Methods Accessible via .str, these allow string operations on every element of a Series. Chained string operations s.str.upper().str.count('A') + +### Working With Values + +- Snippet ID: `item:ks-17e621a20d` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `ks-17e621a20d` + Bucket: `additional` | Type: `source_lecture` + Preview: map() Applies a function (often a lambda) to every element of a Series. Formatting with map df['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g') + +### Working With Values + +- Snippet ID: `item:ks-18a9645168` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `ks-18a9645168` + Bucket: `additional` | Type: `source_lecture` + Preview: Missing Data Represented by np.nan. Use .isna() to detect and .fillna() to replace them. Handling NaNs df.fillna('No value') # Replaces all NaNs + +### Working With Values + +- Snippet ID: `item:ks-2bed6c308f` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `ks-2bed6c308f` + Bucket: `recommended` | Type: `source_lecture` + Preview: isin() A vectorized version of 'in' to check if elements are within a collection. Filtering with isin vowels = list('aeiou') s[s.str[-1].str.lower().isin(vowels)] + +### Working With Values + +- Snippet ID: `item:ks-305a41a33e` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `ks-305a41a33e` + Bucket: `recommended` | Type: `source_lecture` + Preview: Sorting Sort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns. Sorting by column values df.sort_values(by='Length', ascending=False) + +### Working With Values + +- Snippet ID: `item:ks-f8eec928e1` +- Topic: Working With Values +- Card ID: `w5-working-with-values` +- Piece count: `1` + +- `ks-f8eec928e1` + Bucket: `recommended` | Type: `source_lecture` + Preview: Broadcasting Applying a scalar operation (like + or *) to an entire Series or DataFrame automatically. Scalar broadcasting df['Height'] += 10 # Adds 10 to every cell in the column + +## Week 6 + +Snippet families in this group: **36** + +### Comprehensions + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-12-w2-conditions` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-12-w2-conditions` + Bucket: `recommended` | Type: `source_exam` + Preview: You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this? A B C D C Both options implement the conditional logic required to flip the case of each character in t… + +### Comprehensions + +- Snippet ID: `item:kp-manual-comprehension-syntax-d1` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `kp-manual-comprehension-syntax-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Syntax-first comprehension reference Target | Template | Exam cue list | [expr for x in seq if cond] | filter at the end list with else | [a if cond else b for x in seq] | conditional expression stays before `for` dict… + +### Comprehensions + +- Snippet ID: `item:ks-0a4fcae36d` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-0a4fcae36d` + Bucket: `additional` | Type: `source_lecture` + Preview: Generator Comprehensions Created using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory. Generator for large range gen = (x for x in range(100… + +### Comprehensions + +- Snippet ID: `item:ks-0e5c8b8b42` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-0e5c8b8b42` + Bucket: `recommended` | Type: `source_lecture` + Preview: String Transformations via List Comprehension Since 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string. Double vowels in a string s2 =… + +### Comprehensions + +- Snippet ID: `item:ks-1bc815f6d1` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-1bc815f6d1` + Bucket: `additional` | Type: `source_lecture` + Preview: Map and Filter vs. Comprehensions Comprehensions are generally preferred over combining map() and filter() with lambda functions for readability. Equivalent logic using map/filter l2 = list(map(lambda x: x*2, filter(lam… + +### Comprehensions + +- Snippet ID: `item:ks-3e04c4d5e8` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-3e04c4d5e8` + Bucket: `recommended` | Type: `source_lecture` + Preview: Nested Dictionary Comprehensions Allows creating complex nested structures like dictionaries within dictionaries in a single concise line. Dictionary with sub-dictionaries result = {x: {y: x + y for y in range(x, 4)} fo… + +### Comprehensions + +- Snippet ID: `item:ks-72c58bb6b2` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-72c58bb6b2` + Bucket: `additional` | Type: `source_lecture` + Preview: Dictionary Comprehensions with Logic Can include 'if' conditions to filter keys or values during dictionary creation. Filtering dictionary items d = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1} + +### Comprehensions + +- Snippet ID: `item:ks-b9d93f2bc1` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-b9d93f2bc1` + Bucket: `recommended` | Type: `source_lecture` + Preview: Walrus Operator in Comprehensions The walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations. Using walrus to avoid double squarin… + +### Comprehensions + +- Snippet ID: `item:ks-cacc4fbc21` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-cacc4fbc21` + Bucket: `recommended` | Type: `source_lecture` + Preview: Set Comprehensions Creates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order. Building a set of doubled odd numbers s1 = {x * 2 for x in [1, 3, 2… + +### Comprehensions + +- Snippet ID: `item:ks-dd2965ef50` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `1` + +- `ks-dd2965ef50` + Bucket: `additional` | Type: `source_lecture` + Preview: Enumerate in Comprehensions Use enumerate() to access both the index and the value of items within a comprehension. Divide by index plus offset res = [val // (i + 6) for i, val in enumerate([46, 48])] + +### List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + +- Snippet ID: `subtopic:w6-comprehensions:w6-comprehensions-core` +- Topic: Comprehensions +- Card ID: `w6-comprehensions` +- Piece count: `19` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Building a set of doubled odd numbers s1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0} Creates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order. +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Double vowels in a string s2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python']) Since 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them b… +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Dictionary with sub-dictionaries result = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)} Allows creating complex nested structures like dictionaries within dictionaries in a single concise line. +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Using walrus to avoid double squaring l1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10] The walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in… +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Equivalent logic using map/filter l2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4]))) Comprehensions are generally preferred over combining map() and filter() with lambda functions for readability. +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Generator for large range gen = (x for x in range(1000000) if x % 3 == 0) Created using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory. +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Filtering dictionary items d = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1} Can include 'if' conditions to filter keys or values during dictionary creation. +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Divide by index plus offset res = [val // (i + 6) for i, val in enumerate([46, 48])] Use enumerate() to access both the index and the value of items within a comprehension. +- `manual-comprehension-conditional-patterns` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Filter vs transform inside a comprehension flipped = [letter.lower() if letter.isupper() else letter.upper() for letter in letters] positives = [value for value in nums if value > 0] Use trailing `if` to filter items ou… +- `manual-comprehension-syntax-core` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: One-line syntax reference for list, dict, and set comprehensions evens = [x for x in nums if x % 2 == 0] labels = {name: len(name) for name in names} unique_lengths = {len(name) for name in names} These three forms cove… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Creates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Since 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string. +- `kp-3` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Allows creating complex nested structures like dictionaries within dictionaries in a single concise line. +- `kp-4` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: The walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations. +- `kp-5` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Comprehensions are generally preferred over combining map() and filter() with lambda functions for readability. +- `kp-6` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Created using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory. +- `kp-7` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Can include 'if' conditions to filter keys or values during dictionary creation. +- `kp-8` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Use enumerate() to access both the index and the value of items within a comprehension. +- `kp-manual-comprehension-syntax` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns + Preview: Read comprehension syntax left to right: output expression first, then `for`, then an optional trailing `if`; inline `a if cond else b` belongs in the output expression, not after the loop. + +### Datetime + +- Snippet ID: `item:cs-905c77e1f3` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `cs-905c77e1f3` + Bucket: `recommended` | Type: `source_notebook` + Preview: from datetime import datetime from datetime import datetime d = datetime.strptime("2024$05%20","%Y$%m%%%d") print(d) from datetime import datetime d = datetime.strptime("24$05%20","%y$%m%%%d") print(d) from datetime imp… + +### Datetime + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-10-w6-datetime` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-10-w6-datetime` + Bucket: `recommended` | Type: `source_exam` + Preview: Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year? A B C D A Subtracting two datetime objects results in a timedelta object. Accessing the .d… + +### Datetime + +- Snippet ID: `item:exam-intro_python_sample_final_24_25-9-w6-datetime` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `exam-intro_python_sample_final_24_25-9-w6-datetime` + Bucket: `recommended` | Type: `source_exam` + Preview: Suppose that you call the function like this: get_months(["03/02/2013", "03.02.2013", "03-02-2013"]). What does the function call return? A B C D A 1st string: contains '/' so it uses %m/%d/%Y -> month 3. 2nd: contains… + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-day-of-year` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-day-of-year` + Bucket: `keyPoints` | Type: `key_point` + Preview: The day number within the year can be formatted with `%j` or computed with `(dt - datetime(dt.year, 1, 1)).days + 1`. + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-delta` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-delta` + Bucket: `keyPoints` | Type: `key_point` + Preview: Subtracting two datetimes gives a `timedelta`; its most-used direct attributes are `.days`, `.seconds`, and `.microseconds`. + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-format` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-format` + Bucket: `keyPoints` | Type: `key_point` + Preview: `strftime` formats a datetime into text; `strptime` parses text into a datetime object. + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-format-codes` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-format-codes` + Bucket: `keyPoints` | Type: `key_point` + Preview: Memorize the core format codes: `%Y` year, `%m` month, `%d` day, `%H` hour, `%M` minute, `%S` second, `%j` day-of-year. + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-format-codes-d1` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-format-codes-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Core datetime format codes Code | Meaning | Example %Y | 4-digit year | 2024 %m | 2-digit month | 05 %d | 2-digit day | 20 %H | hour (24h) | 14 %M | minute | 30 %S | second | 09 %j | day of year | 141 + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-iso` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-iso` + Bucket: `keyPoints` | Type: `key_point` + Preview: Use `isoformat()` for an ISO-style timestamp, `isoweekday()` for Monday=1..Sunday=7, and `isocalendar()` when you need ISO year/week information. + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-now` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-now` + Bucket: `keyPoints` | Type: `key_point` + Preview: `datetime.now()` gives the current local datetime; use `.timestamp()` only when you specifically need seconds since the Unix epoch. + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-objects-vs-strings` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-objects-vs-strings` + Bucket: `keyPoints` | Type: `key_point` + Preview: `strptime(...)` returns a `datetime`, while `strftime(...)` returns a string. Do arithmetic and attribute access on the datetime object first, then format to text at the end. + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-objects-vs-strings-d1` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-objects-vs-strings-d1` + Bucket: `keyPoints` | Type: `key_point_detail` + Preview: Object vs string workflow Operation | Return type | Can use `.year` / `+ timedelta(...)`? datetime.strptime(...) | datetime | yes dt.strftime(...) | str | no + +### Datetime + +- Snippet ID: `item:kp-manual-datetime-replace` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `kp-manual-datetime-replace` + Bucket: `keyPoints` | Type: `key_point` + Preview: Datetime objects are immutable, so `.replace(...)` returns a new datetime instead of modifying the original one. + +### Datetime + +- Snippet ID: `item:ks-169cc25be1` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `ks-169cc25be1` + Bucket: `recommended` | Type: `source_lecture` + Preview: strptime: String to Date Parses a string into a datetime object based on a provided format template. Parsing a date string from datetime import datetime d = datetime.strptime('2024-05-20', '%Y-%m-%d') + +### Datetime + +- Snippet ID: `item:ks-662456da41` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `ks-662456da41` + Bucket: `additional` | Type: `source_lecture` + Preview: The replace() Method Datetime objects are immutable. The replace() method creates a new datetime object with specific attributes changed. Changing the year of a date from datetime import datetime d = datetime.now().repl… + +### Datetime + +- Snippet ID: `item:ks-755c23c4be` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `ks-755c23c4be` + Bucket: `recommended` | Type: `source_lecture` + Preview: strftime: Date to String Formats a datetime object into a readable string using format codes (e.g., %Y for 4-digit year, %m for month). Formatting a date from datetime import datetime print(datetime.now().strftime('%Y-%… + +### Datetime + +- Snippet ID: `item:ks-86cd7ede1c` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `ks-86cd7ede1c` + Bucket: `recommended` | Type: `source_lecture` + Preview: Timedelta and Date Arithmetic Timedelta objects represent durations. Subtracting two datetimes creates a timedelta; adding a timedelta to a datetime shifts the date. Calculating days difference from datetime import date… + +### Datetime + +- Snippet ID: `item:ks-e643ee5e77` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `ks-e643ee5e77` + Bucket: `recommended` | Type: `source_lecture` + Preview: datetime.now and Timestamps datetime.now() retrieves the current local time. timestamp() returns the seconds since the Unix Epoch (Jan 1, 1970). Getting current timestamp from datetime import datetime print(datetime.now… + +### Datetime + +- Snippet ID: `item:manual-day-of-year` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `manual-day-of-year` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: How can you compute the day number within the year from a datetime? Subtract January 1st of the same year, take `.days`, and add 1 so January 1st becomes day 1. def day_of_year(dt): return (dt - datetime(dt.year, 1, 1))… + +### Datetime + +- Snippet ID: `item:manual-strftime-vs-strptime` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `manual-strftime-vs-strptime` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: When do you use `strftime` versus `strptime`? `strftime` formats a datetime into text; `strptime` parses text into a datetime object. dt.strftime('%Y-%m-%d') datetime.strptime('2024-05-20', '%Y-%m-%d') + +### Datetime + +- Snippet ID: `item:manual-timedelta-attrs` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `1` + +- `manual-timedelta-attrs` + Bucket: `aiQuestions` | Type: `ai_common_question` + Preview: Which attributes exist directly on a `timedelta` object? A `timedelta` stores `days`, `seconds`, and `microseconds`; hours or weeks must be derived or supplied when constructing it. delta = end - start print(delta.days,… + +### now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + +- Snippet ID: `subtopic:w6-datetime:w6-datetime-core` +- Topic: Datetime +- Card ID: `w6-datetime` +- Piece count: `10` + +- `manual-datetime-add-before-format` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Parse, do arithmetic, then format from datetime import datetime, timedelta dt = datetime.strptime('2024-05-20 14:30', '%Y-%m-%d %H:%M') updated = dt + timedelta(days=2, minutes=15) print(updated.strftime('%Y-%m-%d %H:%M… +- `manual-datetime-day-of-year` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Compute the day number within the year from datetime import datetime def day_of_year(dt): return (dt - datetime(dt.year, 1, 1)).days + 1 print(day_of_year(datetime(2024, 5, 20))) Subtract January 1st of the same year, t… +- `manual-datetime-delta` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Subtract datetimes to get a `timedelta` from datetime import datetime start = datetime(2024, 1, 1) end = datetime(2024, 1, 4) print((end - start).days) Datetime subtraction gives a `timedelta`, whose `.days` attribute i… +- `manual-datetime-format` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Format a datetime with `strftime` from datetime import datetime dt = datetime(2024, 5, 20, 14, 30) print(dt.strftime('%Y-%m-%d %H:%M')) Use `strftime` when the exam asks for a formatted string such as year-month-day or… +- `manual-datetime-iso` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: ISO and week-based helpers from datetime import datetime d = datetime(2024, 5, 20) print(d.isoformat()) print(d.isoweekday()) print(d.isocalendar()[1]) Use ISO helpers when the exam asks for an ISO string, the weekday w… +- `manual-datetime-overlap` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Check whether two datetime intervals overlap from datetime import datetime start_a = datetime(2024, 5, 20, 9, 0) end_a = datetime(2024, 5, 20, 11, 0) start_b = datetime(2024, 5, 20, 10, 30) end_b = datetime(2024, 5, 20,… +- `manual-datetime-parse` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Parse text with `strptime` from datetime import datetime dt = datetime.strptime('2024-05-20', '%Y-%m-%d') print(dt) The format string must match the input text exactly, including separators. 2024-05-20 00:00:00 +- `manual-datetime-replace` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: `.replace(...)` returns a new datetime from datetime import datetime d = datetime(2024, 5, 20) print(d.replace(year=2026)) print(d) Datetime objects are immutable, so `.replace(...)` does not modify the original object… +- `manual-datetime-strftime-loop` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Do datetime math before `strftime` turns values into strings from datetime import datetime, timedelta day = datetime(2024, 1, 1) labels = [] for _ in range(3): labels.append(day.strftime("%Y-%m-%d")) day += timedelta(da… +- `manual-datetime-year-month-day` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic + Preview: Datetime attributes stay on the object, not on the formatted string from datetime import datetime dt = datetime.strptime('03-02-2013', '%d-%m-%Y') print(dt.year, dt.month, dt.day) print(dt.strftime('%Y-%m-%d')) After `s… + +### Generators and Iterators + +- Snippet ID: `item:ks-900b394f8e` +- Topic: Generators and Iterators +- Card ID: `w6-generators-and-iterators` +- Piece count: `1` + +- `ks-900b394f8e` + Bucket: `recommended` | Type: `source_lecture` + Preview: Generator Functions Functions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls. Simple step generator def count(start, stop, step): while start <= sto… + +### Generators and Iterators + +- Snippet ID: `item:ks-cd030b9520` +- Topic: Generators and Iterators +- Card ID: `w6-generators-and-iterators` +- Piece count: `1` + +- `ks-cd030b9520` + Bucket: `recommended` | Type: `source_lecture` + Preview: Iterators Objects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted. Manual iteration it = iter([1, 2]); print(next(it)); print(next(it)) + +### Iterator Protocol, Generator Functions, and Generator Comprehensions + +- Snippet ID: `subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core` +- Topic: Generators and Iterators +- Card ID: `w6-generators-and-iterators` +- Piece count: `10` + +- `ai-example-1` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: Simple step generator def count(start, stop, step): while start <= stop: yield start start += step Functions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) betwee… +- `ai-example-2` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: Manual iteration it = iter([1, 2]); print(next(it)); print(next(it)) Objects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted. +- `ai-example-3` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: myiterator = iter([1,3,5]) myiterator = iter([1,3,5]) print(next(myiterator)) print(next(myiterator)) print(next(myiterator)) print(next(myiterator)) +- `ai-example-4` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: class Mylist(list): class Mylist(list): pass myiterator = iter(Mylist([1,3,5])) print(next(myiterator)) print(next(myiterator)) print(next(myiterator)) print(next(myiterator)) +- `ai-example-5` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: mygenerator = (x for x in range(100000000) if x%3 == 0 or x%4 == 0) mygenerator = (x for x in range(100000000) if x%3 == 0 or x%4 == 0) print(next(mygenerator)) print(next(mygenerator)) print(next(mygenerator)) print(ne… +- `ai-example-6` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: class Mylist(list): class Mylist(list): def __iter__ (self): pass myiterator = iter(Mylist([1,3,5])) print(next(myiterator)) print(next(myiterator)) print(next(myiterator)) print(next(myiterator)) +- `ai-example-7` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: def generatorfunction(start, stop, step): def generatorfunction(start, stop, step): while (num:=start) <= stop: yield num start += step return 'End of numbers' for x in generatorfunction(1, 5, 2): print(x) For numeric v… +- `ai-example-8` + Bucket: `aiExamples` | Type: `ai_example` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: def generatorfunction(start, stop, step): def generatorfunction(start, stop, step): while True: num = start start += step if num <= stop: yield num else: return 'End of numbers' print(list(generatorfunction(1, 5, 2))) F… +- `kp-1` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: Functions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls. +- `kp-2` + Bucket: `keyPoints` | Type: `key_point` + Subtopic: Iterator Protocol, Generator Functions, and Generator Comprehensions + Preview: Objects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted. diff --git a/data/vision_exam_pipeline/selectable_items_snapshot.json b/data/vision_exam_pipeline/selectable_items_snapshot.json index 3ef1ddc..c761138 100644 --- a/data/vision_exam_pipeline/selectable_items_snapshot.json +++ b/data/vision_exam_pipeline/selectable_items_snapshot.json @@ -9,7 +9,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do comments start, and what does Python ignore after `#`?\nEverything after `#` on that logical line is ignored by Python.\nx = 3 # this comment does not execute\nprint(x)", - "week": 1 + "week": 1, + "snippet_id": "item:manual-comments", + "snippet_label": "Python Basics" }, { "item_id": "manual-logical-lines", @@ -21,7 +23,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How can one logical line span multiple physical lines?\nUse open brackets or an explicit backslash to continue a statement across lines.\nnumbers = [\n 1,\n 2,\n 3,\n]", - "week": 1 + "week": 1, + "snippet_id": "item:manual-logical-lines", + "snippet_label": "Python Basics" }, { "item_id": "kp-1", @@ -33,7 +37,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Python script is translated line by line into byte code, then byte code is translated into machine code. Writing code must be precise; ambiguities that humans handle fine will cause Python errors.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-python-basics:w1-python-basics-execution-model", + "snippet_label": "Execution Model, Logical Lines, and Comments" }, { "item_id": "ai-example-1", @@ -45,7 +51,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "print('Hello World') # Everything after the hashtag is a comment\nprint('Hello World') # Everything after the hashtag is a comment\nHello World", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-python-basics:w1-python-basics-execution-model", + "snippet_label": "Execution Model, Logical Lines, and Comments" }, { "item_id": "ai-example-2", @@ -57,7 +65,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "print(_, __, ___)\n#\nprint(_, __, ___)", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-python-basics:w1-python-basics-execution-model", + "snippet_label": "Execution Model, Logical Lines, and Comments" }, { "item_id": "ai-example-3", @@ -69,7 +79,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "print('Hello World')\nprint('Hello World')", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-python-basics:w1-python-basics-execution-model", + "snippet_label": "Execution Model, Logical Lines, and Comments" }, { "item_id": "ai-example-4", @@ -81,7 +93,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "print(r\"This gives no \\\" error\")\n#\nprint(r\"This gives no \\\" error\")\nprint(r'This gives no \\' error')", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-python-basics:w1-python-basics-execution-model", + "snippet_label": "Execution Model, Logical Lines, and Comments" }, { "item_id": "ai-example-5", @@ -93,7 +107,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "line_joining\na = 'Two or more physical lines can be joined' +\\\n ' with the help of backward slashes'\nprint(a)", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-python-basics:w1-python-basics-execution-model", + "snippet_label": "Execution Model, Logical Lines, and Comments" }, { "item_id": "ai-example-6", @@ -105,7 +121,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "line_joining\na = ['Two or more physical lines can be joined', \n ' with the help of backward slashes']\nprint(a)", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-python-basics:w1-python-basics-execution-model", + "snippet_label": "Execution Model, Logical Lines, and Comments" }, { "item_id": "ks-95be7f9418", @@ -117,7 +135,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Python execution model\nPython script is translated line by line into byte code, then byte code is translated into machine code. Writing code must be precise; ambiguities that humans handle fine will cause Python errors.", - "week": 1 + "week": 1, + "snippet_id": "item:ks-95be7f9418", + "snippet_label": "Python Basics" }, { "item_id": "cs-09e2b215ee", @@ -129,7 +149,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "print('Hello World') # Everything after the hashtag is a comment\nprint('Hello World') # Everything after the hashtag is a comment\nHello World", - "week": 1 + "week": 1, + "snippet_id": "item:cs-09e2b215ee", + "snippet_label": "Python Basics" }, { "item_id": "cs-814a07a136", @@ -141,7 +163,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "123*1\n#\n123*1", - "week": 1 + "week": 1, + "snippet_id": "item:cs-814a07a136", + "snippet_label": "Python Basics" }, { "item_id": "aiq-1", @@ -153,7 +177,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types.\nI is correct (e.g. a=1, b=2, both int). II is incorrect — if two objects have the same value they must have the same type.\nObjects/types", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-1", + "snippet_label": "Objects and Names" }, { "item_id": "aiq-2", @@ -165,7 +191,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names" }, { "item_id": "aiq-3", @@ -177,7 +205,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should prints:\n[1, 4, 16, 64].\nA mylist = []\nfor i in x:\nmylist[i] = x[i]**2\nprint(mylist)\nB mylist = [0] * len(x)\nfor i in range(len(x)):\nmylist[i] = x[i]**2\nprint(mylist)", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names" }, { "item_id": "aiq-4", @@ -189,7 +219,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, factor=3)\nmultiply(3, 4)\nmultiply()\nA def multiply(*args, factor=2):\ntotal = args[0]", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names" }, { "item_id": "aiq-5", @@ -201,7 +233,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names" }, { "item_id": "aiq-6", @@ -213,7 +247,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-6", + "snippet_label": "Objects and Names" }, { "item_id": "aiq-7", @@ -225,7 +261,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-7", + "snippet_label": "Objects and Names" }, { "item_id": "kp-1", @@ -237,7 +275,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Each object has identity, type, and value. Names bind to objects; rebinding changes the name, while in-place changes only affect mutable objects.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-2", @@ -249,7 +289,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Immutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the same object.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-2-d1", @@ -261,7 +303,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "List is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]", - "week": 1 + "week": 1, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Objects and Names" }, { "item_id": "kp-2-d2", @@ -273,7 +317,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Tuple is immutable — assigning to index raises TypeError\nt1 = (1, 2, 3)\nt1[2] = 4\n# TypeError: 'tuple' object does not support item assignment", - "week": 1 + "week": 1, + "snippet_id": "item:kp-2-d2", + "snippet_label": "Objects and Names" }, { "item_id": "kp-3", @@ -285,7 +331,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Assignment binds the left-hand name to the object produced on the right-hand side.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-3-d1", @@ -297,7 +345,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Basic assignment\nname_1 = 300\nprint(name_1) # 300\nprint(type(name_1)) # \nprint(id(name_1)) # some unique integer", - "week": 1 + "week": 1, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Objects and Names" }, { "item_id": "kp-3-d2", @@ -309,7 +359,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Two names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True", - "week": 1 + "week": 1, + "snippet_id": "item:kp-3-d2", + "snippet_label": "Objects and Names" }, { "item_id": "kp-4", @@ -321,7 +373,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Core built-in types: `int`, `float`, `str`, `bool`, `tuple`, `list`, `dict`, `set`.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-4-d1", @@ -333,7 +387,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "All 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # list\nvar_7 = {'k1': 'v1'} # dict\nvar_8 = {123, '123'} # set", - "week": 1 + "week": 1, + "snippet_id": "item:kp-4-d1", + "snippet_label": "Objects and Names" }, { "item_id": "kp-5", @@ -345,7 +401,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Names can consist of letters (upper/lower), digits, and underscores. Names CANNOT start with a digit. Names ARE case-sensitive (name_1 != Name_1). Avoid Python reserved words (e.g., don't name a variable 'sorted', 'list', 'print').", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-6", @@ -357,7 +415,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Syntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-6-d1", @@ -369,7 +429,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Basic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]", - "week": 1 + "week": 1, + "snippet_id": "item:kp-6-d1", + "snippet_label": "Objects and Names" }, { "item_id": "kp-6-d2", @@ -381,7 +443,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Negative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)", - "week": 1 + "week": 1, + "snippet_id": "item:kp-6-d2", + "snippet_label": "Objects and Names" }, { "item_id": "kp-manual-aliasing-copy", @@ -393,7 +457,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "For mutable objects, `l2 = l1` aliases the same object; use slicing like `l1[:]` when you need an independent copy.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-manual-aliasing-copy-d1", @@ -405,7 +471,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Aliasing vs slicing copy\nl1 = [1, 2, 3]\nl2 = l1\nl3 = l1[:]\nl1[0] = 99\nprint(l2) # [99, 2, 3]\nprint(l3) # [1, 2, 3]", - "week": 1 + "week": 1, + "snippet_id": "item:kp-manual-aliasing-copy-d1", + "snippet_label": "Objects and Names" }, { "item_id": "kp-7", @@ -417,7 +485,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Functions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-7-d1", @@ -429,7 +499,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Simple function\ndef size(length, width):\n return length * width\nprint(size(2,3)) # 6", - "week": 1 + "week": 1, + "snippet_id": "item:kp-7-d1", + "snippet_label": "Objects and Names" }, { "item_id": "kp-8", @@ -441,7 +513,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Which code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "kp-9", @@ -453,7 +527,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Everything in Python is an object. Objects in Python have one id, one value, one type, and zero or more names An assignment statement is one of the ways to create an object. An object created with an assignment statement will have a name, an id, a value and a type.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-1", @@ -465,7 +541,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "List is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]\nImmutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the same object.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-2", @@ -477,7 +555,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Tuple is immutable — assigning to index raises TypeError\nt1 = (1, 2, 3)\nt1[2] = 4\n# TypeError: 'tuple' object does not support item assignment\nImmutable types like `int`, `float`, `str`, and `tuple` cannot change in place. Mutable types like `list`, `dict`, and `set` can be changed through the same object.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-3", @@ -489,7 +569,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Basic assignment\nname_1 = 300\nprint(name_1) # 300\nprint(type(name_1)) # \nprint(id(name_1)) # some unique integer\nAssignment binds the left-hand name to the object produced on the right-hand side.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-4", @@ -501,7 +583,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Two names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True\nAssignment binds the left-hand name to the object produced on the right-hand side.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-5", @@ -513,7 +597,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "All 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # list\nvar_7 = {'k1': 'v1'} # dict\nvar_8 = {123, '123'} # set\nCore built-in types: `int`, `float`, `str`, `bool`, `tuple`, `list`, `dict`, `set`.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-6", @@ -525,7 +611,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Basic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-7", @@ -537,7 +625,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Negative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "manual-objects-aliasing", @@ -549,7 +639,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Aliasing vs slicing copy\nl1 = [1, 2, 3]\nl2 = l1\nl3 = l1[:]\nl1[0] = 99\nprint(l2) # [99, 2, 3]\nprint(l3) # [1, 2, 3]\nFor mutable objects, `l2 = l1` aliases the same object; use slicing like `l1[:]` when you need an independent copy.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "ai-example-8", @@ -561,7 +653,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Simple function\ndef size(length, width):\n return length * width\nprint(size(2,3)) # 6\nFunctions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-objects-and-names:w1-objects-and-names-core", + "snippet_label": "Objects, Types, Mutability, Assignment, and Names" }, { "item_id": "exam-intro_python_sample_final_24_25-13-w1-objects-and-names", @@ -573,7 +667,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What are the outputs of the following lines of code? print(x == y), print(y == z), print(x == z), print(x == y == z)\nA\nB\nC\nD\nA\n'3' == 3 is False. 3 == 3.0 is True. '3' == 3.0 is False. x == y == z evaluates as (x == y) and (y == z), which is False and True, resulting in False.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-intro_python_sample_final_24_25-13-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", @@ -585,7 +681,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers between 0 and 10.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", @@ -597,7 +695,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", @@ -609,7 +709,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\nIf they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?\na\nb\nc\nd\na\nOption A correctly checks if destination is in the list 'europe' using the 'in' operator, and uses 'print' as requested. Option B uses 'return' which is only valid inside a function, and the prompt doesn't mention a function. Option C uses an assignment operator '=' instead of '==' and iterates incorrectly. Option D iterates incorrectly and uses 'return'.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", @@ -621,7 +723,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd like to print the following text to the screen:\n[NAME] has received a grade of [GRADE].\nwhere [NAME] is substituted by the name of the student and [GRADE] is substituted by the actual course grade. The course grade should be displayed to one decimal place after the decimal point.\n\nFor example, if\nstudents = [{\"Name\": \"Adam\", \"Grade\": 7.5}, {\"Name\": \"Bernard\", \"Grade\": 8.0}]\nthen you'd like to see the following two lines printed to the screen:\nAdam has received a grade of 7.5.\nBernard has received a grade of 8.0.\n\nWhich of the following code segments will achieve what you want?\na\nb\nc\nd\na\nOption A correctly iterates over the list of dictionaries and uses f-strings with proper quote escaping (single quotes inside double quotes) and the `:.1f` format specifier to display the float to one decimal place.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-1-w1-objects-and-names", @@ -633,7 +737,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-1-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-3-w1-objects-and-names", @@ -645,7 +751,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, factor=3)\nmultiply(3, 4)\nmultiply()\nA def multiply(*args, factor=2):\ntotal = args[0]\nfor num in args:\ntotal *= num\nreturn total * factor\nB def multiply(*args, factor=2):\nif not args:\nreturn 0\ntotal = args[0]\nfor num in args[1:]:\ntotal *= num\nreturn total * factor\nC Both functions will return the same values.\nD Neither functions will return the same values.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-4-w1-objects-and-names", @@ -657,7 +765,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-7-w1-objects-and-names", @@ -669,7 +779,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called dict_keys that checks whether a certain key is in available in a certain dictionary.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-7-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "ks-e88d0a8060", @@ -681,7 +793,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Objects: core properties\nEvery object has exactly one unique id (cannot change), exactly one type (cannot change), and exactly one value. The type defines what value can be stored and whether the value is mutable or immutable. An object can have zero, one, or more names bound to it. A name can only refer to one object at any time.", - "week": 1 + "week": 1, + "snippet_id": "item:ks-e88d0a8060", + "snippet_label": "Objects and Names" }, { "item_id": "ks-eae9bf47dd", @@ -693,7 +807,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Mutable vs immutable types\nImmutable: int, float, str, bool, tuple. Mutable: list, dict, set. The value of a mutable object CAN be changed in-place. The value of an immutable object CANNOT be changed — a new object must be created.\nList is mutable — can change element in place\nl1 = [1, 2, 3]\nprint(l1) # [1, 2, 3]\nl1[2] = 4\nprint(l1) # [1, 2, 4]\nTuple is immutable — assigning to index raises TypeError\nt1 = (1, 2, 3)\nt1[2] = 4\n# TypeError: 'tuple' object does not support item assignment\nString reassignment creates a NEW object, not mutation\nbox_1 = 'content'\nold_id = id(box_1)\nbox_1 = 'new content'\nnew_id = id(box_1)\nprint(old_id == new_id) # False — different object", - "week": 1 + "week": 1, + "snippet_id": "item:ks-eae9bf47dd", + "snippet_label": "Objects and Names" }, { "item_id": "ks-61c5deec4a", @@ -705,7 +821,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assignment statements — reading right to left\nPython creates a new object with the value on the right, infers type from the value, then binds the name on the left to that object.\nBasic assignment\nname_1 = 300\nprint(name_1) # 300\nprint(type(name_1)) # \nprint(id(name_1)) # some unique integer\nTwo names bound to the same object (same id)\nname_3 = name_4 = name_5 = name_6 = 300\nprint(name_3 is name_4 is name_5 is name_6) # True\nTwo separate objects with equal value (different id)\nname_1 = 300\nname_2 = 300\nprint(name_1 == name_2) # True (same value)\nprint(id(name_1) != id(name_2)) # True (different objects)", - "week": 1 + "week": 1, + "snippet_id": "item:ks-61c5deec4a", + "snippet_label": "Objects and Names" }, { "item_id": "ks-cb3a9e3fd2", @@ -717,7 +835,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Object types — the 8 types to know\nint, float, str, bool, tuple, list, dict, set\nAll 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # list\nvar_7 = {'k1': 'v1'} # dict\nvar_8 = {123, '123'} # set", - "week": 1 + "week": 1, + "snippet_id": "item:ks-cb3a9e3fd2", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-9-w1-objects-and-names", @@ -729,7 +849,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Consider the following code snippet:\nmylist = [1, 2, 5, 7, 9, 12]\nnew_list1 = mylist[0:3]\nnew_list2 = mylist[1:4]\nprint(new_list1 + new_list2)\nWhat will be printed?\nA [1, 2, 5, 7, 2, 5, 7, 9]\nB [1, 2, 5, 2, 5, 7]\nC [2, 5, 7, 5, 7, 9]\nD [2, 5, 5, 7]", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-9-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-11-w1-objects-and-names", @@ -741,7 +863,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Consider the following code snippet:\nx = 10\ny = '5'\nz = x + y\n​What will be the value of 'z' and why?\nA The code will result in a None because 'x' and 'y' have different types.\nB The code will result in an error because you can't add an integer and a string together.\nC The value of z will be '105' because Python concatenates strings.\nD The value of z will be 15 because the string '5' will be implicitly converted to an integer.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-11-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-12-w1-objects-and-names", @@ -753,7 +877,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Which other program will produce the same output as the following code snippet?", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-12-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-14-w1-objects-and-names", @@ -765,7 +891,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Consider the following code snippet:\na = 1\nb = 2.0\nc = '3'\nd = 'hello'\ny = {}\nfor i in [0,1]:\nif i==0:\nif type(a)==type(b):\ny[i] = True\nelse:\ny[i] = False\nif i==1:\nif type(c)==type(d):\ny[i] = True\nelse:\ny[i] = False\nprint(y)\nWhat will this code snippet print?\nA {0: 1, 1: 1}\nB {0: True, 1: True}\nC {0: 0, 1: 1}\nD {0: False, 1: True}", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-14-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-15-w1-objects-and-names", @@ -777,7 +905,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor char in key:\nif char == character:\ncount += 1\ny[key] = count\nreturn y\nWhat would be returned by this function, if we call the function twice as follows:\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'], 'i')\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'])\nA {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 1, 'Julia': 1, 'Ian': 1, 'Noah': 1, 'Liam': 1, 'Anna': 1}\nB The first function call will result in an error because there are too many arguments.\nC The second function call will result in an error because there is a missing argument.\nD {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 0, 'Julia': 0, 'Ian': 0, 'Noah': 0, 'Liam': 0, 'Anna': 0}", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-16-w1-objects-and-names", @@ -789,7 +919,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "What is the output of the program below?", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-16-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-18-w1-objects-and-names", @@ -801,7 +933,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following function which take a list of numerical strings as an argument.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-18-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-20-w1-objects-and-names", @@ -813,7 +947,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "You have the following list:\nmy_list = [1,2,3,4]\nWhich one of the following lines of code lines does not print 4 as the output?\nA print(my_list[4])\nB print(my_list[-1])\nC print(max(my_list))\nD print(len(my_list))", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-20-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-21-w1-objects-and-names", @@ -825,7 +961,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Consider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?\nA y = [1, 2, 3, 4]\nprint('b'+ max(y)*3)\nB print('b' + str(len(x)*3))\nC z = [[\"a\", \"b\", \"c\"], [1, 2, 3, 4]]\nprint(z[0][1] + str(z[1][3])*3)\nD print('b'+ str(8 % 4)*3)", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-21-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-22-w1-objects-and-names", @@ -837,7 +975,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92.0, 98.0, 100.0],\n\"quizzes\": [82.0, 83.0, 91.0],\n\"tests\": [89.0, 97.0]},\n\"david\": {\"name\": \"David\",\n\"homework\": [0.0, 87.0, 75.0, 22.0],\n\"quizzes\": [0.0, 75.0, 78.0],\n\"tests\": [100.0, 100.0]}\n}\nYou want to create a function that calculates the average final course grade of a student.\nThe final course grade is calculated as 20% average homework grade, 10% average quizzes grade and 70% average tests\ngrade.\nWhich of the following programs will work as intended and will give the final course grade of Eva?\nA def average(numbers):\nreturn sum(numbers)/(len(numbers))\ndef final_average(student):\nhomework = average(student['homework'])\nquizzes = average(student['quizzes'])\ntests = average(student['tests'])\nreturn round(0.2*homework + 0.1*quizzes + 0.7*tests, 2)\nfinal_average(students[\"eva\"])\nB def final_average(student):\ndef average(numbers):\nreturn sum(numbers)/(len(numbers)\nhomework = average(student['homework'])\nq…", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-22-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-trial_midterm-24-w1-objects-and-names", @@ -849,7 +989,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA The code will result in an error.\nB True\nC None\nD False\nEnd of test Trial Midterm - Introduction to Python - 23/24", - "week": 1 + "week": 1, + "snippet_id": "item:exam-trial_midterm-24-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-midterm_2023-4-w1-objects-and-names", @@ -861,7 +1003,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Assume you have the following variables:\nx = 'abc'\ny = 3\nz = 2.0\nWhat will be printed after these lines of code?\nprint(x*y)\nprint(x*z)\nprint(y*z)\nA 'abcabcabc'\nThe code will result in a TypeError because you can't multiply a float and a string together.\n6.0\nB The code will result in a ValueError because you can't concatenate a string and an integer.\nThe code will result in a TypeError because you can't multiply a float and a string together.\n6\nC 'abcabcabc'\n'abcabc'\n6.0\nD 'abcabcabc'\nThe code will result in a TypeError because you can't multiply a float and a string together.\n6", - "week": 1 + "week": 1, + "snippet_id": "item:exam-midterm_2023-4-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-midterm_2024-4-w1-objects-and-names", @@ -873,7 +1017,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Consider the following code snippet:\na = 1\nb = 2.0\nc = '3'\nd = 'hello'\ny = {}\nfor i in [0,1]:\nif i==0:\nif type(a)==type(b):\ny[i] = True\nelse:\ny[i] = False\nif i==1:\nif type(c)==type(d):\ny[i] = True\nelse:\ny[i] = False\nprint(y)\nWhat will this code snippet print?\nA {0: False, 1: True}\nB {0: True, 1: True}\nC {0: 0, 1: 1}\nD {0: 1, 1: 1}", - "week": 1 + "week": 1, + "snippet_id": "item:exam-midterm_2024-4-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-midterm_2024-6-w1-objects-and-names", @@ -885,7 +1031,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Consider the following code snippet:\nx = 10\ny = '5'\nz = x + y\n​What will be the value of 'z' and why?\nA The value of z will be 15 because the string '5' will be implicitly converted to an integer.\nB The value of z will be '105' because Python concatenates strings.\nC The code will result in an error because you can't add an integer and a string together.\nD The code will result in a None because 'x' and 'y' have different types.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-midterm_2024-6-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "exam-extra_practice-11-w1-objects-and-names", @@ -897,7 +1045,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "x = ['abc', [[]], (1, 2), {}, True, 3.0, 4]\n\nWhat is the output of the following code snippet?\n\nprint(type(float(x[2][0] + x[2][1])) == type(x[-2]))\na\nb\nc\nd\nd\nx[2] = (1,2). x[2][0]=1, x[2][1]=2. 1+2=3. float(3)=3.0. type(3.0)=float. x[-2]=3.0 (index 5). type(3.0)=float. float==float → True.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-extra_practice-11-w1-objects-and-names", + "snippet_label": "Objects and Names" }, { "item_id": "ks-d79a1899f6", @@ -909,7 +1059,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Names / variable naming rules\nNames can consist of letters (upper/lower), digits, and underscores. Names CANNOT start with a digit. Names ARE case-sensitive (name_1 != Name_1). Avoid Python reserved words (e.g., don't name a variable 'sorted', 'list', 'print').", - "week": 1 + "week": 1, + "snippet_id": "item:ks-d79a1899f6", + "snippet_label": "Objects and Names" }, { "item_id": "ks-6f41148083", @@ -921,7 +1073,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Slicing\nSyntax: seq[start:end:step]. Start is inclusive, end is NOT inclusive. Defaults: start=0, end=len, step=1. Negative step goes from right to left. Slicing always creates a NEW object of the same type.\nBasic slicing examples\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[7]) # 8\nprint(l1[-1]) # 8\nprint(l1[-5:5]) # [4, 5]\nprint(l1[:-5]) # [1, 2, 3]\nNegative step\nl1 = [1, 2, 3, 4, 5, 6, 7, 8]\nprint(l1[5:1:-2]) # [6, 4]\nprint(l1[5::-1]) # [6, 5, 4, 3, 2, 1]\nprint(l1[:1:-1]) # [8, 7, 6, 5, 4, 3]\nprint(l1[1:5:-2]) # [] (already past end)\nSlice reversal\nl1 = [1, 2, 3, 4]\nprint(l1[::-1]) # [4, 3, 2, 1]\nSlicing creates new object — key exam trap\nl1 = [1, 2, 3, 4]\nl2 = l1\nl3 = l1[:]\nl1[-1] = 5\nprint(l1 == l2, l2 == l3) # True False (l3 is independent copy)\nChanging a list slice vs index\nl1 = [1, 2, 3, 4, 5, 6]\nl1[1:2] = [1, 1] # replaces element at index 1 with two elements\nprint(l1) # [1, 1, 1, 3, 4, 5, 6]\n\nl1 = [1, 2, 3, 4, 5, 6]\nl1[1] = [1, 1] # replaces element at index 1 with a list\nprint(l1) # [1, [1, 1], 3, 4, 5, 6]\nSlicing strings and tuples\nt1 = (1, 2, 3)\nprint(t1[1:]) # (2, 3)\ns1 = 'uva Amsterdam'\nprint(s1[5:-3:2]) # 'mtr'\nChanging string/tuple (must create new object)\ns1 = 'uva Amsterdam'\n# s1[6] = 's' # ERROR\ns1 = s1[:6] + 's' + s1[7:]\nprint(s1) # works\n\nt1 = (1, 4, 3)\n# t1[1] = 2 # ERROR\nt1 = t1[:1] + (2,) + t1[2:]\nprint(t1) # works", - "week": 1 + "week": 1, + "snippet_id": "item:ks-6f41148083", + "snippet_label": "Objects and Names" }, { "item_id": "ks-0153de2f70", @@ -933,7 +1087,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Functions — basics\nFunctions are objects. Defined with def. Called with (). Built-in functions: print, id, len, type, del. Functions can return values. Methods are functions attached to objects.\nSimple function\ndef size(length, width):\n return length * width\nprint(size(2,3)) # 6", - "week": 1 + "week": 1, + "snippet_id": "item:ks-0153de2f70", + "snippet_label": "Objects and Names" }, { "item_id": "ks-df3b849d59", @@ -945,7 +1101,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Exam question types\nWhich code fragment will print the following output? / What will be printed by the following code fragment? / Which code fragment prints the SAME output as...? / One fragment prints different output from the others. / Which correctly solves the problem? Options may include: 'None of the above', 'Both', 'All', 'An error'.", - "week": 1 + "week": 1, + "snippet_id": "item:ks-df3b849d59", + "snippet_label": "Objects and Names" }, { "item_id": "ks-419e787b39", @@ -957,7 +1115,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "objects\n### Everything in Python is an object. Objects in Python have one id, one value, one type, and zero or more names\n
                    An assignment statement is one of the ways to create an object. An object created with an assignment statement will have a name, an id, a value and a type.\n
                    If you know the name you can ask for the id, the value, and the type", - "week": 1 + "week": 1, + "snippet_id": "item:ks-419e787b39", + "snippet_label": "Objects and Names" }, { "item_id": "aiq-1", @@ -969,7 +1129,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What is the result of (a//b)*b + a%b?\nArithmetic operators", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-1", + "snippet_label": "Operators and Truth" }, { "item_id": "aiq-2", @@ -981,7 +1143,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Boolean operator precedence: not > and > or\na==1 or a==2 and b==1 or b==2 is evaluated as a==1 or (a==2 and b==1) or b==2", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-2", + "snippet_label": "Operators and Truth" }, { "item_id": "kp-1", @@ -993,7 +1157,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "a+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b)*b + a%b == a always.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "kp-1-d1", @@ -1005,7 +1171,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Floor division and modulo\nprint(5 // 3, 5 % 3) # 1 2\nprint(-5 // 3, -5 % 3) # -2 1\nprint(5 // 2, 5 % 2) # 2 1\nprint(-5 // 2, -5 % 2) # -3 1", - "week": 1 + "week": 1, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Operators and Truth" }, { "item_id": "kp-2", @@ -1017,7 +1185,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal;", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "kp-2-d1", @@ -1029,7 +1199,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Float precision issue\nprint(1.1 + 2.2 == 3.3) # False", - "week": 1 + "week": 1, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Operators and Truth" }, { "item_id": "kp-2-d2", @@ -1041,7 +1213,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "List/tuple comparison\nprint([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less)\nprint([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0)", - "week": 1 + "week": 1, + "snippet_id": "item:kp-2-d2", + "snippet_label": "Operators and Truth" }, { "item_id": "kp-3", @@ -1053,7 +1227,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "x and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then 'or'. Use parentheses to avoid confusion.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "kp-3-d1", @@ -1065,7 +1241,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Precedence trap\na=1; b=3\nprint(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter)\nprint((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT)", - "week": 1 + "week": 1, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Operators and Truth" }, { "item_id": "ai-example-1", @@ -1077,7 +1255,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Floor division and modulo\nprint(5 // 3, 5 % 3) # 1 2\nprint(-5 // 3, -5 % 3) # -2 1\nprint(5 // 2, 5 % 2) # 2 1\nprint(-5 // 2, -5 % 2) # -3 1\na+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b)*b + a%b == a always.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ai-example-2", @@ -1089,7 +1269,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Float precision issue\nprint(1.1 + 2.2 == 3.3) # False\n==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal;", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ai-example-3", @@ -1101,7 +1283,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "List/tuple comparison\nprint([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less)\nprint([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0)\n==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal;", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ai-example-4", @@ -1113,7 +1297,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Precedence trap\na=1; b=3\nprint(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter)\nprint((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT)\nx and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then 'or'. Use parentheses to avoid confusion.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ai-example-5", @@ -1125,7 +1311,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "arithmetic_operators\nprint(5//2, 5%2)\n2 1", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ai-example-6", @@ -1137,7 +1325,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "arithmetic_operators\nprint(4 + 3)\nprint(4 - 3)\nprint(4 * 3)\nprint(4 / 3)\nprint(4 / 2)\nprint(4 ** 3)\n7\n1\n12\n1.3333333333333333\n2.0\n64", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ai-example-7", @@ -1149,7 +1339,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "arithmetic_operators\nprint(5 // 3, 5 % 3)\nprint(-5 // 3, -5 % 3)\nprint(5 // 2, 5 % 2)\nprint(-5 // 2, -5 % 2)\n1 2\n-2 1\n2 1\n-3 1", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ai-example-8", @@ -1161,7 +1353,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`==` versus `is`\n#\nimport random # The random module that can be used to generate pseudo-random numbers is part of the standard Python installation\n # but the name has still to be importent\na = random.randint(3, 9) # This generates an integer between 3 and 9 (both included), it is given the name 'a'\nb = random.randint(3, 9) # # This generates an integer between 3 and 9 (both included), it is given the name 'b'\nprint (a, b)\nprint(a==(a/b)*b + a%b) # == compares what is left of it to what is right of it and evaluates to True if both sides evaluate to the same value\n`==` compares value equality; `is` compares whether two names refer to the same object.\n8 4\nTrue", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-operators-and-truth:w1-operators-and-truth-core", + "snippet_label": "Arithmetic, Comparison, and Boolean Operators" }, { "item_id": "ks-03c874b8bb", @@ -1173,7 +1367,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Arithmetic operators\na+b, a-b, a*b: standard. a/b: always returns float. a//b: floor division (highest integer <= result). a%b: remainder. a**b: exponentiation. NOTE: ^ is NOT exponentiation in Python (it is XOR). (a//b)*b + a%b == a always.\nFloor division and modulo\nprint(5 // 3, 5 % 3) # 1 2\nprint(-5 // 3, -5 % 3) # -2 1\nprint(5 // 2, 5 % 2) # 2 1\nprint(-5 // 2, -5 % 2) # -3 1", - "week": 1 + "week": 1, + "snippet_id": "item:ks-03c874b8bb", + "snippet_label": "Operators and Truth" }, { "item_id": "ks-c0135e2a4a", @@ -1185,7 +1381,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Comparison operators\n==, !=, >, <, >=, <=. Always return True or False. Comparing floats can be tricky: 1.1+2.2 != 3.3 in Python due to floating-point precision. String/tuple/list comparison is element-by-element left to right; first differing element decides; if equal length and no differences, they are equal; shorter sequence is 'less than' longer if all elements match up to shorter length.\nFloat precision issue\nprint(1.1 + 2.2 == 3.3) # False\nList/tuple comparison\nprint([1, 2, 3] < [1, 2, 3, 0]) # True (shorter is less)\nprint([2] < [1, 2, 3, 0]) # False (2 > 1 at index 0)", - "week": 1 + "week": 1, + "snippet_id": "item:ks-c0135e2a4a", + "snippet_label": "Operators and Truth" }, { "item_id": "ks-c815ffe1d5", @@ -1197,7 +1395,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Boolean operators\nx and y: True only if both True. x or y: False only if both False. not x: inverts. NOTE: && and || are Python operators but do something different (bitwise). Precedence: 'not' first, then 'and', then 'or'. Use parentheses to avoid confusion.\nPrecedence trap\na=1; b=3\nprint(a==1 or a==2 and b==1 or b==2) # True (WRONG: and binds tighter)\nprint((a==1 or a==2) and (b==1 or b==2)) # False (CORRECT)", - "week": 1 + "week": 1, + "snippet_id": "item:ks-c815ffe1d5", + "snippet_label": "Operators and Truth" }, { "item_id": "cs-7eb8617d28", @@ -1209,7 +1409,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "arithmetic_operators\nprint(5//2, 5%2)\n2 1", - "week": 1 + "week": 1, + "snippet_id": "item:cs-7eb8617d28", + "snippet_label": "Operators and Truth" }, { "item_id": "cs-3cb4b8e8f9", @@ -1221,7 +1423,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "arithmetic_operators\nprint(4 + 3)\nprint(4 - 3)\nprint(4 * 3)\nprint(4 / 3)\nprint(4 / 2)\nprint(4 ** 3)\n7\n1\n12\n1.3333333333333333\n2.0\n64", - "week": 1 + "week": 1, + "snippet_id": "item:cs-3cb4b8e8f9", + "snippet_label": "Operators and Truth" }, { "item_id": "cs-266616a010", @@ -1233,7 +1437,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "arithmetic_operators\nprint(5 // 3, 5 % 3)\nprint(-5 // 3, -5 % 3)\nprint(5 // 2, 5 % 2)\nprint(-5 // 2, -5 % 2)\n1 2\n-2 1\n2 1\n-3 1", - "week": 1 + "week": 1, + "snippet_id": "item:cs-266616a010", + "snippet_label": "Operators and Truth" }, { "item_id": "cs-4f8a5f420b", @@ -1245,7 +1451,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "arithmetic_operators\n#\nimport random # The random module that can be used to generate pseudo-random numbers is part of the standard Python installation\n # but the name has still to be importent\na = random.randint(3, 9) # This generates an integer between 3 and 9 (both included), it is given the name 'a'\nb = random.randint(3, 9) # # This generates an integer between 3 and 9 (both included), it is given the name 'b'\nprint (a, b)\nprint(a==(a/b)*b + a%b) # == compares what is left of it to what is right of it and evaluates to True if both sides evaluate to the same value\n8 4\nTrue", - "week": 1 + "week": 1, + "snippet_id": "item:cs-4f8a5f420b", + "snippet_label": "Operators and Truth" }, { "item_id": "aiq-1", @@ -1257,7 +1465,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Slicing / mutability\nTrack which names point to the same object and which slice creates a copy before the mutation happens.\nSlicing / mutability", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-1", + "snippet_label": "Sequences and Access" }, { "item_id": "aiq-2", @@ -1269,7 +1479,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Slicing negative step\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.\nSlicing negative step", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-2", + "snippet_label": "Sequences and Access" }, { "item_id": "aiq-3", @@ -1281,7 +1493,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Correct. c: [::-1] reverses to [10,9,8,7,6,5,4,3,2,1], then [::2] takes every 2nd: [10,8,6,4,2]. Correct. d: [::2] gives [1,3,5,7,9], then [::-1] reverses: [9,7,5,3,1]. This does NOT give [10,8,6,4,2].\nExam • extra_practice • Q6", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-3", + "snippet_label": "Sequences and Access" }, { "item_id": "aiq-5", @@ -1293,7 +1507,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-5", + "snippet_label": "Sequences and Access" }, { "item_id": "aiq-6", @@ -1305,7 +1521,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "range() and slicing both exclusive at stop\nrange(1,10,3)→[1,4,7] not including 10; l[2:7] goes up to but not including index 7", - "week": 1 + "week": 1, + "snippet_id": "item:aiq-6", + "snippet_label": "Sequences and Access" }, { "item_id": "kp-1", @@ -1317,7 +1535,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Negative indices count from the end: `seq[-1]` is last and `seq[-len(seq)]` is first.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "kp-1-d1", @@ -1329,7 +1549,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nPattern | Meaning | Example\nseq[i] | single element | x[-1]\nseq[a:b] | start inclusive, stop exclusive | x[1:4]\nseq[::-1] | reverse copy | x[::-1]\nseq[::2] | step through every other item | x[::2]", - "week": 1 + "week": 1, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Sequences and Access" }, { "item_id": "kp-2", @@ -1341,7 +1563,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`range(start, stop, step)` excludes `stop`; defaults are `start=0` and `step=1`, just like slicing excludes the stop index.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "kp-2-d1", @@ -1353,7 +1577,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "range examples\nprint(list(range(6))) # [0, 1, 2, 3, 4, 5]\nprint(list(range(3,6))) # [3, 4, 5]\nprint(list(range(3,6,2))) # [3, 5]", - "week": 1 + "week": 1, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Sequences and Access" }, { "item_id": "kp-3", @@ -1365,7 +1591,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Pattern to remember: subset = numbers[::2][::-1]", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "ai-example-1", @@ -1377,7 +1605,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "range() output patterns\nprint(list(range(6))) # [0, 1, 2, 3, 4, 5]\nprint(list(range(3,6))) # [3, 4, 5]\nprint(list(range(3,6,2))) # [3, 5]\n`range(start, stop, step)` excludes `stop`; defaults are `start=0` and `step=1`, just like slicing excludes the stop index.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "ai-example-2", @@ -1389,7 +1619,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "print(\"This is a string\")\nprint(\"This is a string\")\nprint('This is another string')", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "ai-example-4", @@ -1401,7 +1633,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "String quotes and escaping\nprint(\"This gives no ' error\")\nprint('This gives no \" error')", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "ai-example-5", @@ -1413,7 +1647,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "a = 'This is a string'\na = 'This is a string' \nb = \"This is another string\"\nprint(a)\nprint(b)\nprint(a,b)", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "ai-example-6", @@ -1425,7 +1661,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "a = 'This is a string'; b = 6; c = 0.0\n#\na = 'This is a string'; b = 6; c = 0.0 \nprint(f\"We know {a =}, {b= }, and {c = }\")", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "ai-example-7", @@ -1437,7 +1675,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "slicing\nl1 = ['a', 'b']\nl2 = l1\nl2[-1] = 'c'\nprint(l1 == l3)\nl3 = l1[::]\nl3[-1] = 'c'\nprint(l1 == l3)", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-sequences-and-access:w1-sequences-and-access-core", + "snippet_label": "Indexing, Slicing, and range()" }, { "item_id": "exam-intro_python_sample_final_24_25-18-w2-conditions", @@ -1449,7 +1689,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "How do you break a list into a list of lists, where each sublist contains 3 elements?\nA\nB\nC\nD\nA\nOption A uses range(0, 7, 3) which generates 0, 3, 6. The slices x[0:3], x[3:6], and x[6:9] correctly partition the list.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-intro_python_sample_final_24_25-18-w2-conditions", + "snippet_label": "Sequences and Access" }, { "item_id": "exam-extra_practice-6-w1-sequences-and-access", @@ -1461,7 +1703,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Correct. c: [::-1] reverses to [10,9,8,7,6,5,4,3,2,1], then [::2] takes every 2nd: [10,8,6,4,2]. Correct. d: [::2] gives [1,3,5,7,9], then [::-1] reverses: [9,7,5,3,1]. This does NOT give [10,8,6,4,2]. Correct answer (the one that does NOT work): d.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "snippet_label": "Sequences and Access" }, { "item_id": "ks-685cd3d828", @@ -1473,7 +1717,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Indexing\nForward: 0, 1, 2, ... len-1. Backward: -1 (last), -2 (second to last), ..., -len (first). l1[0] == l1[-len(l1)]", - "week": 1 + "week": 1, + "snippet_id": "item:ks-685cd3d828", + "snippet_label": "Sequences and Access" }, { "item_id": "ks-be78ccac04", @@ -1485,7 +1731,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "range()\nrange(start, stop, step). start default=0, step default=1. Stop is NOT inclusive. Works like slicing but defaults differ slightly.\nrange examples\nprint(list(range(6))) # [0, 1, 2, 3, 4, 5]\nprint(list(range(3,6))) # [3, 4, 5]\nprint(list(range(3,6,2))) # [3, 5]", - "week": 1 + "week": 1, + "snippet_id": "item:ks-be78ccac04", + "snippet_label": "Sequences and Access" }, { "item_id": "cs-curated-hw-seq-nth-occurrence", @@ -1497,7 +1745,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Find the nth occurrence by advancing .index()\nx = ['A', 'B', 'A', 'C', 'B', 'A', 'B']\nn = 2\ni = -1\nfor _ in range(n):\n i = x.index('B', i + 1)\nprint(i)\n4", - "week": 1 + "week": 1, + "snippet_id": "item:cs-curated-hw-seq-nth-occurrence", + "snippet_label": "Sequences and Access" }, { "item_id": "cs-curated-hw-seq-slice-between-sentinels", @@ -1509,7 +1759,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Slice between two sentinel values without hard-coding indices\nx = [21, 15, 29, 20, 15, 21, 38, 26]\nleft = x.index(15) + 1\nright = left + x[left:].index(15)\nprint(x[left:right])\n[29, 20]", - "week": 1 + "week": 1, + "snippet_id": "item:cs-curated-hw-seq-slice-between-sentinels", + "snippet_label": "Sequences and Access" }, { "item_id": "manual-import-names", @@ -1521,7 +1773,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do different import forms change the names you can use locally?\n`import math` gives `math.sqrt`, `import math as m` gives `m.sqrt`, and `from math import sqrt` gives `sqrt(...)` directly.\nimport math\nimport math as m\nfrom math import sqrt", - "week": 1 + "week": 1, + "snippet_id": "item:manual-import-names", + "snippet_label": "Functions and Imports" }, { "item_id": "manual-print-vs-return", @@ -1533,7 +1787,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What is the difference between printing a value and returning a value from a function?\n`print(x)` shows a value on screen. `return x` sends a value back to the caller so it can be stored, reused, or printed later.\ndef f(x):\n return x + 1\n\nprint(f(3))", - "week": 1 + "week": 1, + "snippet_id": "item:manual-print-vs-return", + "snippet_label": "Functions and Imports" }, { "item_id": "manual-implicit-none", @@ -1545,7 +1801,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What does a function return if it reaches the end without `return`?\nPython returns `None` if no `return` statement is executed.\ndef f():\n print('hi')\n\nprint(f())", - "week": 1 + "week": 1, + "snippet_id": "item:manual-implicit-none", + "snippet_label": "Functions and Imports" }, { "item_id": "kp-1", @@ -1557,7 +1815,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "kp-1-d1", @@ -1569,7 +1829,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Import styles\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import randint as rnd\nrnd(1, 10) # works\nrandint(1, 10) # ERROR", - "week": 1 + "week": 1, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Functions and Imports" }, { "item_id": "kp-1-d2", @@ -1581,7 +1843,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nCall | Use | Typical result\nint('123') | string to integer | 123\nfloat('123') | string to float | 123.0\nstr(123.0) | number to string | '123.0'\nround(x, 2) | round for display/checking | 2 decimals", - "week": 1 + "week": 1, + "snippet_id": "item:kp-1-d2", + "snippet_label": "Functions and Imports" }, { "item_id": "kp-2", @@ -1593,7 +1857,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "ai-example-1", @@ -1605,7 +1871,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import randint as rnd\nrnd(1, 10) # works\nrandint(1, 10) # ERROR\n`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "ai-example-2", @@ -1617,7 +1885,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Direct import plus alias binds both names\nclear_names()\n\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n2025\nname 'extension' is not defined", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "ai-example-3", @@ -1629,7 +1899,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "from-import binds only the imported name\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n2025\n2025", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "ai-example-4", @@ -1641,7 +1913,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n2026\nname 'YEAR' is not defined", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "ai-example-5", @@ -1653,7 +1927,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "import module does not create bare globals\nclear_names()\n\nfrom extension import create_absolute_year as cay\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(cay(1))\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\nname 'create_absolute_year' is not defined\n2026", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "ai-example-6", @@ -1665,7 +1941,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Import module under its original name\nclear_names()\ntry:\n print(YEAR)\nexcept Exception as e:\n print(Exception)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n\nimport extension\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ... import ...`, or `as`.\n\nname 'extension' is not defined\nname 'YEAR' is not defined\n2025", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "ai-example-8", @@ -1677,7 +1955,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95,000\n4 32% $95,000\nIf your gross income is $50,000, you will pay 10% tax on the first $11,000, 12% tax on the next $34,000 and 22% tax on the last $5,000.\nWhich of the following function will return the output containing your net_income and your total_tax given your gross_income?\nFor example:\nIf we call the function as:\nincome_tax_calculator(50000)\nit should return:\n{'total_tax': 6280.0, 'net_income': 43720.0}\nA def income_tax_calculator(gross_income):\nresults = {}\nrate_1 = 0.10\nrate_2 = 0.12\nrate_3 = 0.22\nrate_4 = 0.32\nbracket_1 = 11000\nbracket_2 = 45000 - 11000\nbracket_3 = 95000 - 45000\nif gross_income > 95000:\ntotal_tax = ((gross_income - 95000) * rate_4) + (bracket_3 * rate_3) + (bracket_2 * rate_2)\n+ (bracket_1 * rate_1)\nelif 95000 >= gross_income > 45000:\ntotal_tax = ((gross_income - 45000) * rate_3) + (bracket_2 * rate_2) + (bracket_1 * rate_1)\nelif 45000 >= gross_income > 11000:\ntotal_tax = ((gross_income - 11000) * rate_2) + (bracket_1 * rate_1)\nelse:\ntotal_tax = gross_income * rate_1\nnet_income = gross_income - total_tax\nresults['total_tax'] = round(total_tax, 2)\nresults['net_income'] = round(net_income, 2)\nreturn results\nB def income_tax_calculator(gross_income):\n​ results = {}\nrate_1 = 0.10\nrate_2 = 0.12\nrate_3 = 0.22\nrate_4 = 0.32\nbracket_1 = 11000\nbracket_2 = 45000 - 11001\nbracket_3 = 95000 - 45001\ntotal_tax = (gross_income - 95001) * rate_4 + (bracket_3 * rate_3) + (bracket_2 * rate_2) +\n(bracket_1 * rate_1)\nnet_income = lambda gross_income, total_tax: gross_income - total_tax\nresults['total_tax'] = round(total_tax, 2)\nresults['net_income'] = round(net_income, 2)\nreturn results\nC def income_tax_calculator(gross_income):\n​ results = {}\nrate_1 = 0.10\nrate_2 = 0.12\nrate_3 = 0.22\nrate_4 = 0.32\nif gross_income <= 11000:\ntotal_tax = gross_income * rate_1\nif 45000 > gross_income > 11000:\ntotal_tax += (45000 - gross_income) * rate_2\nif 95000 > gross_income > 45000:\ntotal_tax += (95000 - gross_income) * rate_3\nelse:\ntotal_tax += (gross_income - 95000) * rate_4\nnet_income = gross_income - total_tax\nresults['total_tax'] = total_tax\nresults['net_income'] = net_income\nreturn(total_tax, net_income)\nD All of three functions will work as intended.\nCheck branch boundaries, rounding, and whether the function returns `{'total_tax': ..., 'net_income': ...}`.", - "week": 1 + "week": 1, + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules" }, { "item_id": "exam-intro_python_sample_final_24_25-24-w2-conditions", @@ -1689,7 +1969,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which script does NOT print the correct answer for the area of a circle?\nA\nB\nC\nD\nC\nIf math is imported as constants, it must be referred to as 'constants.pi'. 'math.pi' will no longer be available unless 'math' was also imported directly.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-intro_python_sample_final_24_25-24-w2-conditions", + "snippet_label": "Functions and Imports" }, { "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", @@ -1701,7 +1983,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B uses list slicing `x[::-2]` which steps backwards through `x` by 2, retrieving indices -1, -3, -5, -7, and -9, which correspond to 5, 4, 3, 2, 1. Thus, both A and B are correct.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports" }, { "item_id": "exam-midterm_2023-12-w1-functions-and-imports", @@ -1713,7 +1997,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You want to write a program to calculate your income tax for 2023.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-midterm_2023-12-w1-functions-and-imports", + "snippet_label": "Functions and Imports" }, { "item_id": "exam-midterm_2024-15-w1-functions-and-imports", @@ -1725,7 +2011,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, 9]\nB [2, 4, 6, 8, 10]\nC [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nD None", - "week": 1 + "week": 1, + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports" }, { "item_id": "exam-midterm_2024-16-w1-functions-and-imports", @@ -1737,7 +2025,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather alert system.", - "week": 1 + "week": 1, + "snippet_id": "item:exam-midterm_2024-16-w1-functions-and-imports", + "snippet_label": "Functions and Imports" }, { "item_id": "ks-f43422a4cf", @@ -1749,7 +2039,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Importing packages\nMultiple import styles. 'import X' makes X available. 'import X as Y' renames. 'from X import Z' brings Z directly into namespace. 'from X import Z as W' renames. Once you use 'as', the original name is no longer accessible.\nImport styles\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import randint as rnd\nrnd(1, 10) # works\nrandint(1, 10) # ERROR", - "week": 1 + "week": 1, + "snippet_id": "item:ks-f43422a4cf", + "snippet_label": "Functions and Imports" }, { "item_id": "ks-b6a39f66a2", @@ -1761,7 +2053,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
                    • A function is a grouping of code that can perform a certain task and can be re-used \n
                    • Print is a built-in function, that is a function that is part of the standard implementation of Python. Built-in fuctions like any function, can be used by calling their name. Built-in functions are already copied to your computer and the names of some of them like print, don't need to be imported\n
                    • User functions are functions defined by you or other people that are not part of the standard Python implementation. (You will learn how to write your own…", - "week": 1 + "week": 1, + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports" }, { "item_id": "cs-beb6591b24", @@ -1773,7 +2067,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "imports\nclear_names()\n\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n2025\nname 'extension' is not defined", - "week": 1 + "week": 1, + "snippet_id": "item:cs-beb6591b24", + "snippet_label": "Functions and Imports" }, { "item_id": "cs-6d0d650063", @@ -1785,7 +2081,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "imports\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n2025\n2025", - "week": 1 + "week": 1, + "snippet_id": "item:cs-6d0d650063", + "snippet_label": "Functions and Imports" }, { "item_id": "cs-4155022ebf", @@ -1797,7 +2095,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "imports\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\n2026\nname 'YEAR' is not defined", - "week": 1 + "week": 1, + "snippet_id": "item:cs-4155022ebf", + "snippet_label": "Functions and Imports" }, { "item_id": "cs-23b2cfd4d6", @@ -1809,7 +2109,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "imports\nclear_names()\n\nfrom extension import create_absolute_year as cay\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(cay(1))\nexcept Exception as e:\n print(e)\nname 'create_absolute_year' is not defined\n2026", - "week": 1 + "week": 1, + "snippet_id": "item:cs-23b2cfd4d6", + "snippet_label": "Functions and Imports" }, { "item_id": "cs-5b89a10dcd", @@ -1821,7 +2123,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "imports\nclear_names()\ntry:\n print(YEAR)\nexcept Exception as e:\n print(Exception)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n\nimport extension\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\n\nname 'extension' is not defined\nname 'YEAR' is not defined\n2025", - "week": 1 + "week": 1, + "snippet_id": "item:cs-5b89a10dcd", + "snippet_label": "Functions and Imports" }, { "item_id": "cs-c25503e5db", @@ -1833,7 +2137,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "imports\n%%writefile extension.py\n# In this cell we create a python file and write that to the hard disk (either of your computer or to the cloud depending where you run your code.\n# We will import this file to show how to import the names of objects \n# into your Python program\nYEAR = 2025\ndef create_absolute_year(x):\n return YEAR + x\nOverwriting extension.py", - "week": 1 + "week": 1, + "snippet_id": "item:cs-c25503e5db", + "snippet_label": "Functions and Imports" }, { "item_id": "aiq-1", @@ -1845,7 +2151,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • trial_midterm • Q2", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-1", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "aiq-2", @@ -1857,7 +2165,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Which update makes `library['books'] = 6` and adds `library['years']`?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q8", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-2", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "aiq-3", @@ -1869,7 +2179,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1, 2, 3, 4]\nC [11, 22, 33, 44]\nD [(1, 10), (2, 20), (3, 30), (4, 40)]", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-3", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "aiq-6", @@ -1881,7 +2193,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "RuntimeError: dictionary changed size during iteration\nAdding or deleting dict entries while iterating over it causes RuntimeError", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-6", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "kp-1", @@ -1893,7 +2207,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Dicts map unique immutable keys to values. `key in d` checks keys, and equality ignores insertion order.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "kp-1-d1", @@ -1905,7 +2221,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Creating and using dicts\ncapitals = {}\ncapitals = dict()\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nprint(capitals['Belgium']) # Brussels\ndel(capitals['Belgium']) # delete key\ncapitals['Netherlands'] = 'Amsterdam' # insert/update\ncapitals.update({'France': 'Paris'}) # insert/update multiple", - "week": 2 + "week": 2, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "kp-1-d2", @@ -1917,7 +2235,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dict membership checks KEYS, not values\nd = {1: 4, 2: 3}\nprint(1 in d) # True (1 is a key)\nprint(4 in d) # False (4 is a value, not a key)", - "week": 2 + "week": 2, + "snippet_id": "item:kp-1-d2", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "kp-1-d3", @@ -1929,7 +2249,23 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nOperation | What it gives | Exam note\nd[key] | value lookup | Key must exist\nkey in d | membership on keys | not values\nd.items() | (key, value) pairs | good for loops\nd.update(...) | mutates dict | returns None", - "week": 2 + "week": 2, + "snippet_id": "item:kp-1-d3", + "snippet_label": "Dictionaries and Mappings" + }, + { + "item_id": "kp-1-d4", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Construction and lookup patterns\nPattern | What it does | Exam use\n{'a': 1} | literal dict | fastest way to show known pairs\ndict() | empty dict | start building inside a loop\ndict(zip(keys, values)) | pairs two iterables | good when keys and values already exist separately\nd.get(key, default) | safe lookup | avoids KeyError when a key may be missing", + "week": 2, + "snippet_id": "item:kp-1-d4", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "kp-2", @@ -1941,7 +2277,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use `.keys()`, `.values()`, and `.items()` for dictionary views; looping over a dict directly gives keys.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "kp-2-d1", @@ -1953,7 +2291,37 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Looping over dict\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nfor key in capitals.keys():\n print(key)\nfor val in capitals.values():\n print(val)\nfor key, value in capitals.items():\n print(key, value)\n# These two are equivalent:\nfor key in capitals:\nfor key in capitals.keys():", - "week": 2 + "week": 2, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Dictionaries and Mappings" + }, + { + "item_id": "kp-2-d2", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Iteration and ordering reminders\nPattern | Iterates over | Trap\nfor key in d | keys | same as for key in d.keys()\nfor value in d.values() | values | no keys available unless you ask for them\nfor key, value in d.items() | (key, value) tuples | best when both are needed\nfor key in sorted(d) | keys in sorted order | use this when output order matters", + "week": 2, + "snippet_id": "item:kp-2-d2", + "snippet_label": "Dictionaries and Mappings" + }, + { + "item_id": "kp-2-d3", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Dictionary equality ignores insertion order\nprint({1: 1, 2: 2} == {2: 2, 1: 1})\nprint([1, 2] == [2, 1])", + "week": 2, + "snippet_id": "item:kp-2-d3", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "ai-example-1", @@ -1965,7 +2333,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Creating and using dicts\ncapitals = {}\ncapitals = dict()\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nprint(capitals['Belgium']) # Brussels\ndel(capitals['Belgium']) # delete key\ncapitals['Netherlands'] = 'Amsterdam' # insert/update\ncapitals.update({'France': 'Paris'}) # insert/update multiple\nDicts map unique immutable keys to values. `key in d` checks keys, and equality ignores insertion order.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "ai-example-2", @@ -1977,7 +2347,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Dict membership checks KEYS, not values\nd = {1: 4, 2: 3}\nprint(1 in d) # True (1 is a key)\nprint(4 in d) # False (4 is a value, not a key)\nDicts map unique immutable keys to values. `key in d` checks keys, and equality ignores insertion order.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "ai-example-4", @@ -1989,7 +2361,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Dictionary creation and lookup\nsquares = {1:1, 2:4, 3:9, 4:16}\nprint(squares)\nl1 = [1, 2, 3, 4]\nl2 = [1, 4, 9, 16]\nsquares = dict(zip(l1, l2))\nprint(squares)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "ai-example-5", @@ -2001,7 +2375,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Dictionary creation and lookup\nsquares = {}\nprint(squares)\nsquares = dict()\nprint(squares)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "ai-example-6", @@ -2013,7 +2389,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Dictionary creation and lookup\nsquares = {1:1, 2:4, 3:9, 4:16}\ndel(squares[2])\nprint(squares)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "ai-example-7", @@ -2025,7 +2403,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Dictionary creation and lookup\na = 1\nb = {1:1}\nprint({a:b})\ntry:\n print({b:a})\nexcept Exception as e:\n print(e)\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "ai-example-8", @@ -2037,7 +2417,23 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Dictionary creation and lookup\ncapitals = {'Estonia': 'Tallinn', 'Belgium': 'Brussels', 'France': 'Paris'}\nprint(capitals['Belgium'])\nCheck whether the code is looking up a key, iterating with `.items()`, or mutating the dictionary.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" + }, + { + "item_id": "manual-dict-construction-and-iteration", + "card_id": "w2-dictionaries-and-mappings", + "topic": "Dictionaries and Mappings", + "subtopic_id": "w2-dictionaries-and-mappings-core", + "subtopic_title": "Creation, Lookup, Updates, and Key Constraints", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Construct, iterate, count, and sort dictionaries\nwords = ['pear', 'apple', 'pear']\ncounts = {}\nfor word in words:\n counts[word] = counts.get(word, 0) + 1\nprint(dict(zip(['a', 'b'], [1, 2])))\nfor key in sorted(counts):\n print(key, counts[key])\nprint(sum(counts.values()))\nThis bundles the recurring exam mechanics: `dict(zip(...))`, safe counting with `.get(...)`, deterministic iteration with `sorted(...)`, and totals via `sum(d.values())`.\n{'a': 1, 'b': 2}\napple 1\npear 2\n3", + "week": 2, + "snippet_id": "subtopic:w2-dictionaries-and-mappings:w2-dictionaries-and-mappings-core", + "snippet_label": "Creation, Lookup, Updates, and Key Constraints" }, { "item_id": "exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", @@ -2049,7 +2445,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which of the following programs correctly returns a dictionary where values are sums of input values whose keys are <= the output key?\nA\nB\nC\nD\nC\nBoth methods correctly calculate the cumulative sums based on key values, though Option B is more efficient.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-intro_python_sample_final_24_25-19-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", @@ -2061,7 +2459,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What is the result of the program comparing d1 (from zip) and d2 (from enumerate)?\nA\nB\nC\nD\nA\nBoth d1 and d2 result in the same dictionary: {1: 2, 2: 3, 3: 4, 4: 5}.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-intro_python_sample_final_24_25-20-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", @@ -2073,7 +2473,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", @@ -2085,7 +2487,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A correctly zips the numbers 1 to 5 with the corresponding Roman numerals to create the dictionary.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", @@ -2097,7 +2501,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A correctly iterates through both lists simultaneously using zip and assigns the correct keys and values.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", @@ -2109,7 +2515,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A correctly identifies the maximum rating from the values and then prints the corresponding employees.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", @@ -2121,7 +2529,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a valid dictionary comprehension that iterates through `words`, setting each `word` as the key and `len(word)` as the value.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", @@ -2133,7 +2543,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the following code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97\na\nb\nc\nd\nc\nOption A iterates over 'aeiou' and correctly creates the dictionary. Option B iterates over 'aeiou' and also checks if the vowel is in 'aeiou', which is redundant but still valid and produces the correct dictionary. Thus, both work correctly.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", @@ -2145,7 +2557,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a new dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?\na\nb\nc\nd\na\nOption A uses zip to combine the lists and enumerate with start=1 to get match numbers starting from 1. It assigns a tuple of goals to each match number. Option B assigns the sum instead of a tuple. Options C and D don't use start=1 for enumerate, so keys will start from 0.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", @@ -2157,7 +2571,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?\na\nb\nc\nd\na\nDictionaries are not sliceable, so options B and D will raise TypeErrors. Option C creates a list of tuples, and the sum() function cannot add tuples together in this context (it will raise a TypeError when trying to add an int to a tuple). Option A extracts the first three keys, gets their corresponding values in a list comprehension, and calculates the average correctly.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial_midterm-2-w2-dictionaries-and-mappings", @@ -2169,7 +2585,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-2-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", @@ -2181,7 +2599,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"],\n- change the value of the key \"books\" to 6.\nThe new value of the dictionary library should be:\n{\"books\" : 6,\n\"genres\" : ['action', 'romance', 'thriller', 'classics'],\n\"years\" : [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]}\nWhich of the programs below will work as intended?\nA library[\"books\"] = 6\nlibrary.update({\"years\": [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]})\nB library[\"books\"] = 6\nlibrary[\"years\"] = [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]\nC Both of the given options\nD None of the given options", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", @@ -2193,7 +2613,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1, 2, 3, 4]\nC [11, 22, 33, 44]\nD [(1, 10), (2, 20), (3, 30), (4, 40)]", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", @@ -2205,7 +2627,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_count = my_count_function(\"peach\")\nWhich of the code snippets of code below prints something different than the other code snippets?\nA print(len(apple_count.keys()))\nB print(len(peach_count.keys()))\nC print(sum(apple_count.values()))\nD print(sum(peach_count.values()))", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "ks-65c4de2e9d", @@ -2217,7 +2641,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Dictionaries\nSets of key:value pairs. Keys must be unique and immutable (hashable). Dictionaries are unordered for equality ({1:1,2:2}=={2:2,1:1} is True). Cannot be sorted. You can check membership with 'in' — this checks KEYS only. Keys() gives key sequence, values() gives value sequence, items() gives tuples.\nCreating and using dicts\ncapitals = {}\ncapitals = dict()\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nprint(capitals['Belgium']) # Brussels\ndel(capitals['Belgium']) # delete key\ncapitals['Netherlands'] = 'Amsterdam' # insert/update\ncapitals.update({'France': 'Paris'}) # insert/update multiple\nDict membership checks KEYS, not values\nd = {1: 4, 2: 3}\nprint(1 in d) # True (1 is a key)\nprint(4 in d) # False (4 is a value, not a key)\nCreating dict from two lists\nl1 = [1, 2, 3, 4]\nl2 = [1, 4, 9, 16]\nsquares = dict(zip(l1, l2))\nprint(squares) # {1:1, 2:4, 3:9, 4:16}\nDict equality ignores order\nprint({1:1, 2:2} == {2:2, 1:1}) # True\nprint([1,2] == [2,1]) # False", - "week": 2 + "week": 2, + "snippet_id": "item:ks-65c4de2e9d", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "ks-adb6d9f967", @@ -2229,7 +2655,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Looping over dictionaries\n.keys() → key sequence. .values() → value sequence. .items() → sequence of (key, value) tuples. 'for key in dict' is the same as 'for key in dict.keys()'.\nLooping over dict\ncapitals = {'Andorra': 'Andorra la Vella', 'Belgium': 'Brussels'}\nfor key in capitals.keys():\n print(key)\nfor val in capitals.values():\n print(val)\nfor key, value in capitals.items():\n print(key, value)\n# These two are equivalent:\nfor key in capitals:\nfor key in capitals.keys():", - "week": 2 + "week": 2, + "snippet_id": "item:ks-adb6d9f967", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-trial_midterm-23-w2-dictionaries-and-mappings", @@ -2241,7 +2669,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "You have to write a function called summarize which take a list of integers as an argument.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-23-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2023-5-w2-dictionaries-and-mappings", @@ -2253,7 +2683,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "What is the output of the program below?", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2023-6-w2-dictionaries-and-mappings", @@ -2265,7 +2697,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following dictionary:\nsample_dict = {\n\"name\": \"Kim\",\n\"age\": 25,\n\"birthdate\": \"3-2-1998\",\n\"city\": \"Amsterdam\"}\nSuppose you want to create a dictionary that only contains the keys 'name' and 'city'.\nWhich of the following code snippets return(s) the desired dictionary?\nA keys = [\"name\", \"city\"]\nnew_dict = {}\nfor k in keys:\nnew_dict[k] = sample_dict[k]\nnew_dict\nB keys = [\"age\", \"birthdate\"]\nnew_dict = {}\nnew_keys = sample_dict.keys() - keys\nfor k in new_keys:\nnew_dict[k] = sample_dict[k]\nnew_dict\nC None of the given options\nD Both of the given options", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", @@ -2277,7 +2711,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\" becomes 7\nSo the final dictionary should look like:\n{'shirts': 7, 'colors': ['red', 'yellow', 'blue', 'pink'], 'shoes': ['sneakers', 'heels']}\nWhich of the programs below will work as intended?\nA shoes = {'shoes': ['sneakers', 'heels']}\ncloset[\"shirts\"] = 7\ncloset = dict(zip(closet, shoes))\nB closet.keys() = closet.keys() + \"shoes\"\ncloset.values() = [7, ['red', 'yellow', 'blue', 'pink'], ['sneakers', 'heels']]\nC Both of the given options\nD None of the given options", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2023-8-w2-dictionaries-and-mappings", @@ -2289,7 +2725,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\ncounts[letter] = string.count(letter)\nreturn counts\nAnd you create the following two dictionaries:\ndesk_count = my_count_function(\"desk\")\nlaptop_count = my_count_function(\"laptop\")\nWhich of the lines of code below returns something different than the rest?\nA len(desk_count)\nB max(laptop_count.values())*2\nC sum(desk_count.values())\nD sum(laptop_count.keys())", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", @@ -2301,7 +2739,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92.0, 98.0, 100.0],\n\"quizzes\": [82.0, 83.0, 91.0],\n\"tests\": [89.0, 97.0]},\n\"david\": {\"name\": \"David\",\n\"homework\": [0.0, 87.0, 75.0, 22.0],\n\"quizzes\": [0.0, 75.0, 78.0],\n\"tests\": [100.0, 100.0]}\n}\nYou want to create a function that calculates the average final course grade of a student.\nThe final course grade is calculated as 20% average homework grade, 10% average quizzes grade and 70% average tests grade.\nWhich of the following programs will work as intended and will give the final course grade of Eva?\nA def average(numbers):\nreturn sum(numbers)/(len(numbers))\ndef final_average(student):\nhomework = average(student['homework'])\nquizzes = average(student['quizzes'])\ntests = average(student['tests'])\nreturn round(0.2*homework + 0.1*quizzes + 0.7*tests, 2)\nfinal_average(students[\"eva\"])\nB def final_average(student):\ndef average(numbers):\nreturn sum(numbers)/(len(numbers)\nhomework = average(student['home…", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2024-8-w2-dictionaries-and-mappings", @@ -2313,7 +2753,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "You need to write a function called dict_keys that checks whether a certain key is in available in a certain dictionary.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2024-10-w2-dictionaries-and-mappings", @@ -2325,7 +2767,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"],\n- change the value of the key \"books\" to 6.\nThe new value of the dictionary library should be:\n{\"books\" : 6,\n\"genres\" : ['action', 'romance', 'thriller', 'classics'],\n\"years\" : [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]}\nWhich of the programs below will work as intended?\nA library[\"books\"] = 6\nlibrary.update({\"years\": [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]})\nB library[\"books\"] = 6\nlibrary[\"years\"] = [\"1932\" , \"2012\", \"1899\", \"2000\", \"1984\"]\nC Both of the given options\nD None of the given options", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2024-11-w2-dictionaries-and-mappings", @@ -2337,7 +2781,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_count = my_count_function(\"peach\")\nWhich of the code snippets of code below prints something different than the other code snippets?\nA print(sum(apple_count.values()))\nB print(len(apple_count.keys()))\nC print(sum(peach_count.values()))\nD print(len(peach_count.keys()))", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-11-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-midterm_2024-12-w2-dictionaries-and-mappings", @@ -2349,7 +2795,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA [10, 20, 30, 40, 1, 2, 3, 4]\nB [11, 22, 33, 44]\nC This code will result in an error because you cannot concatenate two lists using the + operator.\nD [(1, 10), (2, 20), (3, 30), (4, 40)]", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-12-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", @@ -2361,7 +2809,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and lowest scores and the values are a list of names of the players that attained the corresponding scores.\n\nWhich of the following code snippets implements this?\na\nb\nc\nd\nc\nBoth snippets correctly find the global max (6) and min (1), then iterate to find which players achieved those scores. Both produce the same correct output. Note: both Adelbrecht and Hortensia achieved score 6, so winners = ['Adelbrecht', 'Hortensia'].", - "week": 2 + "week": 2, + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", @@ -2373,7 +2823,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the for loop is indented under the average_score line as if it's a block, but there's no colon). This causes an IndentationError. Option b works correctly. Actually option a depends on whether the indentation shown is a tab after a plain statement — in Python that's an IndentationError. So only b works. Correct: b.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", @@ -2385,7 +2837,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a correctly counts grades: initialises to 0 and increments. Produces {9:3, 10:2, 11:1}. Option b creates lists of student names, not counts — produces {9:['A','C','F'], 10:['B','E'], 11:['D']}, not the required format. Correct: a.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-extra_practice-8-w2-dictionaries-and-mappings", @@ -2397,7 +2851,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "x = {'a': [1, 2], 'b':[3, 4], 'c':[5, 6], 'd':[7, 8]}\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\na: x['a'][1]=2, x['b'][0]=3, 2*3=6, x['c'][1]=6. True. b: x['b'][0]=3, x['c'][0]=5, 3+5=8, x['d'][1]=8. True. c: x['d'][0]=7, x['c'][0]=5, 7-5=2, x['a'][1]=2. True. All are True, so d is correct.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-extra_practice-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "exam-extra_practice-12-w2-dictionaries-and-mappings", @@ -2409,7 +2865,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "def counter(y):\n\tx = {}\n\tfor index, element in enumerate(y):\n\t\tif index != int(element) and int(element) % 2 == 0:\n\t\t\tx[element] = len(element)\n\treturn x\n\nWhat will this function return when called as:\ncounter(['12345678', '1', '123', '1234', '12345', '12', '6', '1', '123456'])\na\nb\nc\nd\na\nindex 0: '12345678', int=12345678, index(0)!=12345678 ✓, even ✓ → add, len=8. index 1: '1', int=1, index==int → skip. index 2: '123', int=123, odd → skip. index 3: '1234', int=1234, index(3)!=1234 ✓, even ✓ → add, len=4. index 4: '12345', int=12345, odd → skip. index 5: '12', int=12, index(5)!=12 ✓, even ✓ → add, len=2. index 6: '6', int=6, index(6)==6 → skip. index 7: '1', int=1, odd → skip. index 8: '123456', int=123456, index(8)!=123456 ✓, even ✓ → add, len=6. Result: {'12345678':8,'1234':4,'12':2,'123456':6}. Correct: a.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-extra_practice-12-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "cs-curated-hw-dict-digit-frequency", @@ -2421,7 +2879,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Count only digit characters that actually appear\nx = ['1', 'a', 'X', '2', 'b', 'Y', '1', 'a', 'X', '1', 'a', 'X']\ncounts = {}\nfor digit in '0123456789':\n if digit in x:\n counts[digit] = x.count(digit)\nprint(counts)\n{'1': 3, '2': 1}", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-dict-digit-frequency", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "cs-curated-hw-dict-delete-shared-keys", @@ -2433,7 +2893,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Delete keys only when they also appear in a reference dict\nx = {'a': 1, 'b': 2, 'c': 3}\nto_remove = {'c': 3, 'd': 3}\nfor key in to_remove:\n if key in x:\n del x[key]\nprint(x)\n{'a': 1, 'b': 2}", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-dict-delete-shared-keys", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "cs-curated-hw-dict-project-values-sorted-keys", @@ -2445,7 +2907,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Sort keys first, then project values in that order\nx = {1: 3, 3: 4, 2: 5}\nsorted_keys = sorted(x.keys(), reverse=True)\nresult = [x[key] for key in sorted_keys]\nprint(result)\n[4, 5, 3]", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-dict-project-values-sorted-keys", + "snippet_label": "Dictionaries and Mappings" }, { "item_id": "aiq-1", @@ -2457,7 +2921,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Assume you already have a variable a, which is an integer between 1 and 4.\nExam • midterm_2023 • Q15\nmylist = [1, 3, 5, 7, 9]\nprint(mylist[a] + mylist[-a])", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-1", + "snippet_label": "Lists and Sets" }, { "item_id": "aiq-2", @@ -2469,7 +2935,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-2", + "snippet_label": "Lists and Sets" }, { "item_id": "aiq-3", @@ -2481,7 +2949,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-3", + "snippet_label": "Lists and Sets" }, { "item_id": "aiq-4", @@ -2493,7 +2963,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False", - "week": 2 + "week": 2, + "snippet_id": "item:aiq-4", + "snippet_label": "Lists and Sets" }, { "item_id": "kp-1", @@ -2505,7 +2977,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Lists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "kp-1-d1", @@ -2517,7 +2991,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Ordering comparison\nprint([1,2] == [2,1]) # False (ordered)\nprint((1,2) == (2,1)) # False (ordered)\nprint('12' == '21') # False (ordered)\nprint({1,2} == {2,1}) # True (unordered)\nprint({1:1,2:2}=={2:2,1:1}) # True (unordered)", - "week": 2 + "week": 2, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Lists and Sets" }, { "item_id": "kp-2", @@ -2529,7 +3005,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Unordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update().", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "kp-2-d1", @@ -2541,7 +3019,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Set operations\ncountries = set() # empty set (NOT {})\ncountries = {'Andorra', 'Belgium'}\nprint({1,2,2} == {2,1}) # True (duplicates ignored)\nprint(len({1,2,2})) # 2\ncountries.remove('Andorra')\ncountries.add('Greece')\ncountries.update({'Spain', 'Italy'})", - "week": 2 + "week": 2, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Lists and Sets" }, { "item_id": "ai-example-1", @@ -2553,7 +3033,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Ordering comparison\nprint([1,2] == [2,1]) # False (ordered)\nprint((1,2) == (2,1)) # False (ordered)\nprint('12' == '21') # False (ordered)\nprint({1,2} == {2,1}) # True (unordered)\nprint({1:1,2:2}=={2:2,1:1}) # True (unordered)\nLists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "ai-example-2", @@ -2565,7 +3047,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Set operations\ncountries = set() # empty set (NOT {})\ncountries = {'Andorra', 'Belgium'}\nprint({1,2,2} == {2,1}) # True (duplicates ignored)\nprint(len({1,2,2})) # 2\ncountries.remove('Andorra')\ncountries.add('Greece')\ncountries.update({'Spain', 'Italy'})\nUnordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update().", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "ai-example-3", @@ -2577,7 +3061,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Create a list literal\nsquares = [1, 4, 9, 16]\nprint(squares)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "ai-example-4", @@ -2589,7 +3075,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Delete by index with `del`\nsquares = [1, 4, 5, 9, 16]\ndel(squares[2])\nprint(squares)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "ai-example-5", @@ -2601,7 +3089,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Two ways to create an empty list\nsquares = []\nprint(squares)\nsquares = list()\nprint(squares)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "ai-example-6", @@ -2613,7 +3103,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Lists are mutable: replace by index\nsquares = [1, 4, 8, 15]\nsquares[2] = 9\nsquares[3] = 16\nprint(squares)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "ai-example-7", @@ -2625,7 +3117,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "List method effects and resulting list\nsquares = [1, 4, 9, 16]\nsquares.append(16)\nsquares.append(25)\nprint(squares)\nCheck whether the method mutates the list in place and what the list looks like after each call.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "ai-example-8", @@ -2637,7 +3131,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "List method effects and resulting list\nif 16 not in squares:\n squares.append(16)\nif 25 not in squares:\n squares.append(25) \nprint(squares)\nCheck whether the method mutates the list in place and what the list looks like after each call.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-lists-and-sets:w2-lists-and-sets-core", + "snippet_label": "Sequences, Uniqueness, and Common Operations" }, { "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", @@ -2649,7 +3145,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", @@ -2661,7 +3159,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", @@ -2673,7 +3173,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by 2 elements at a time, picking the second instance of each number in reverse order, which also yields [5, 4, 3, 2, 1]. Both work.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", @@ -2685,7 +3187,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-midterm_2023-15-w2-lists-and-sets", @@ -2697,7 +3201,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assume you already have a variable a, which is an integer between 1 and 4.\nWhat is the ​output of the following ​code snippet?", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-15-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-midterm_2023-16-w2-lists-and-sets", @@ -2709,7 +3215,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC 0\nD None of the given options.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-midterm_2024-22-w2-lists-and-sets", @@ -2721,7 +3229,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?\nA z = [[\"a\", \"b\", \"c\"], [1, 2, 3, 4]]\nprint(z[0][1] + str(z[1][3])*3)\nB print('b'+ str(8 % 4)*3)\nC print('b' + str(len(x)*3))\nD y = [1, 2, 3, 4]\nprint('b'+ max(y)*3)", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-22-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-midterm_2024-23-w2-lists-and-sets", @@ -2733,7 +3243,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\nmylist = [1, 2, 5, 7, 9, 12]\nnew_list1 = mylist[0:3]\nnew_list2 = mylist[1:4]\nprint(new_list1 + new_list2)\nWhat will be printed?\nA [1, 2, 5, 2, 5, 7]\nB [1, 2, 5, 7, 2, 5, 7, 9]\nC [2, 5, 7, 5, 7, 9]\nD [2, 5, 5, 7]", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-23-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "ks-4258f15a6c", @@ -2745,7 +3257,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Lists vs Dictionaries vs Sets — ordered/unordered\nLists, tuples, strings are SEQUENCES (ordered). Dicts and sets are NOT sequences (unordered for equality). All are called collections.\nOrdering comparison\nprint([1,2] == [2,1]) # False (ordered)\nprint((1,2) == (2,1)) # False (ordered)\nprint('12' == '21') # False (ordered)\nprint({1,2} == {2,1}) # True (unordered)\nprint({1:1,2:2}=={2:2,1:1}) # True (unordered)", - "week": 2 + "week": 2, + "snippet_id": "item:ks-4258f15a6c", + "snippet_label": "Lists and Sets" }, { "item_id": "ks-08ac820c2f", @@ -2757,7 +3271,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Sets\nUnordered collection of unique values. Empty set MUST be set() — {} creates empty dict. Elements must be immutable. No indexing. Methods: .add(), .remove(), .update().\nSet operations\ncountries = set() # empty set (NOT {})\ncountries = {'Andorra', 'Belgium'}\nprint({1,2,2} == {2,1}) # True (duplicates ignored)\nprint(len({1,2,2})) # 2\ncountries.remove('Andorra')\ncountries.add('Greece')\ncountries.update({'Spain', 'Italy'})", - "week": 2 + "week": 2, + "snippet_id": "item:ks-08ac820c2f", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-midterm_2024-24-w2-lists-and-sets", @@ -2769,7 +3285,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "You have the following list:\nmy_list = [1,2,3,4]\nWhich one of the following lines of code lines does not print 4 as the output?\nA print(max(my_list))\nB print(len(my_list))\nC print(my_list[4])\nD print(my_list[-1])", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-24-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "exam-extra_practice-1-w2-lists-and-sets", @@ -2781,7 +3299,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\nb\nc\nd\nd\nOption a: for (1,2,2), tuple has no .count() — wait, actually tuples DO have .count(). For [1,2,2]: element 2 has count>1 so counter=2, returns False. Original returns False. But for a tuple (1,2,2): tuple has .count(), works. But option b: l1[l1.index(element)+1:] — tuples support slicing and indexing too. Let's re-examine: for a tuple (1,2,2), both a and b should work the same. Actually option a counts ALL duplicated elements (counts 2 twice for [1,2,2]), making counter=2, so counter==0 is False. Original is False too. Both match. For option b applied to tuple: l1[l1.index(element)+1:] works for tuples too. Actually both a and b return same values as original. Correct: d.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets" }, { "item_id": "manual-bool-precedence", @@ -2793,7 +3313,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do `not`, `and`, and `or` combine when there are no extra parentheses?\n`not` is evaluated first, then `and`, then `or`, so parenthesize whenever the intended logic is not obvious.\nprint(not False and True or False)", - "week": 2 + "week": 2, + "snippet_id": "item:manual-bool-precedence", + "snippet_label": "Conditions" }, { "item_id": "manual-filter-condition", @@ -2805,7 +3327,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Trace `main(lst, condition)` and identify which values satisfy `lambda x: x % 2 != 0`.\nApply the condition to one element first, then keep only the values for which it returns `True`.\ndef main(lst, condition):\n return [x for x in lst if condition(x)]", - "week": 2 + "week": 2, + "snippet_id": "item:manual-filter-condition", + "snippet_label": "Conditions" }, { "item_id": "manual-conditional-expression", @@ -2817,7 +3341,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "When should you use `x if cond else y` instead of a multi-line `if/else` block?\nUse the conditional expression for a single value choice; use a full block when each branch needs multiple statements.\nlabel = 'pass' if score >= 10 else 'fail'", - "week": 2 + "week": 2, + "snippet_id": "item:manual-conditional-expression", + "snippet_label": "Conditions" }, { "item_id": "kp-manual-precedence", @@ -2829,7 +3355,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`not` binds tighter than `and`, and `and` binds tighter than `or`; add parentheses when the intended grouping is not obvious.", - "week": 2 + "week": 2, + "snippet_id": "item:kp-manual-precedence", + "snippet_label": "Conditions" }, { "item_id": "kp-manual-ternary", @@ -2841,7 +3369,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use `x if cond else y` when both branches are single expressions; use a full `if/elif/else` block when the branches need multiple statements.", - "week": 2 + "week": 2, + "snippet_id": "item:kp-manual-ternary", + "snippet_label": "Conditions" }, { "item_id": "ai-example-1", @@ -2853,7 +3383,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Precedence trap\na=1; b=3\n# WRONG: Python evaluates 'and' before 'or'\nprint(a==1 or a==2 and b==1 or b==2) # True (unexpected)\n# CORRECT: use brackets\nprint((a==1 or a==2) and (b==1 or b==2)) # False\nPrecedence (high to low): comparisons → not → and → or. Use parentheses to be explicit. 'in' checks membership in sequence/set/dict-keys.\nTrue\nFalse", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conditions:w2-conditions-core", + "snippet_label": "Comparisons, `in`, Precedence, and Conditional Expressions" }, { "item_id": "ai-example-2", @@ -2865,7 +3397,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Inclusion check — 'in' operator\nprint(1 in [1,2,3]) # True\nprint(1 in (1,2,3)) # True\nprint('1' in '123') # True (substring)\nprint(1 in {1:4, 2:3}) # True (checks keys)\nprint(4 in {1:4, 2:3}) # False (4 is value, not key)\nprint(1 in {1,2,3}) # True\nPrecedence (high to low): comparisons → not → and → or. Use parentheses to be explicit. 'in' checks membership in sequence/set/dict-keys.\nTrue\nTrue\nTrue\nTrue\nFalse\nTrue", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conditions:w2-conditions-core", + "snippet_label": "Comparisons, `in`, Precedence, and Conditional Expressions" }, { "item_id": "ai-example-3", @@ -2877,7 +3411,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "if/elif/else structure\nif condition_1:\n expression_1\nelif condition_2:\n expression_2\n expression_3\nelse:\n expression_4\nif/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critical — all code in a block must have same indentation. Conditional expression (ternary): value_if_true if condition else value_if_false.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conditions:w2-conditions-core", + "snippet_label": "Comparisons, `in`, Precedence, and Conditional Expressions" }, { "item_id": "ai-example-4", @@ -2889,7 +3425,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Conditional expression (ternary)\n# Statement form:\nif a > 0:\n b = a\nelse:\n b = 0\n# Expression form:\nb = a if a > 0 else 0\n# Even simpler:\nb = max(0, a)\nif/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critical — all code in a block must have same indentation. Conditional expression (ternary): value_if_true if condition else value_if_false.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conditions:w2-conditions-core", + "snippet_label": "Comparisons, `in`, Precedence, and Conditional Expressions" }, { "item_id": "ai-example-5", @@ -2901,7 +3439,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Comparison operators return booleans\nprint(3 > 2)\nA comparison like `3 > 2` evaluates to either `True` or `False`.\nTrue", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conditions:w2-conditions-core", + "snippet_label": "Comparisons, `in`, Precedence, and Conditional Expressions" }, { "item_id": "ai-example-8", @@ -2913,7 +3453,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`not` flips booleans\nprint(not True) \nprint(not False)\n`not True` becomes `False` and `not False` becomes `True`.\nFalse\nTrue", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conditions:w2-conditions-core", + "snippet_label": "Comparisons, `in`, Precedence, and Conditional Expressions" }, { "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", @@ -2925,7 +3467,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?\na\nb\nc\nd\na\nOption A correctly removes spaces, converts to lowercase, lists characters, sorts them, and compares the results. Option B and C use .sort() which returns None, and D uses .replace() on a list.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions" }, { "item_id": "exam-midterm_2023-1-w2-conditions", @@ -2937,7 +3481,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What is the output of the following code snippet?", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-1-w2-conditions", + "snippet_label": "Conditions" }, { "item_id": "exam-midterm_2024-2-w2-conditions", @@ -2949,7 +3495,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions" }, { "item_id": "exam-trial_midterm-6-w2-conditions", @@ -2961,7 +3509,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\nC [1, 3, 5, 7, 9]\nD None", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions" }, { "item_id": "exam-trial_midterm-13-w2-conditions", @@ -2973,7 +3523,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called weather_alert that accepts a string argument, which is a color code of the weather\nalert system.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-13-w2-conditions", + "snippet_label": "Conditions" }, { "item_id": "ks-4b427a2425", @@ -2985,7 +3537,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Conditions and boolean operators — precedence\nPrecedence (high to low): comparisons → not → and → or. Use parentheses to be explicit. 'in' checks membership in sequence/set/dict-keys.\nPrecedence trap\na=1; b=3\n# WRONG: Python evaluates 'and' before 'or'\nprint(a==1 or a==2 and b==1 or b==2) # True (unexpected)\n# CORRECT: use brackets\nprint((a==1 or a==2) and (b==1 or b==2)) # False\nInclusion check — 'in' operator\nprint(1 in [1,2,3]) # True\nprint(1 in (1,2,3)) # True\nprint('1' in '123') # True (substring)\nprint(1 in {1:4, 2:3}) # True (checks keys)\nprint(4 in {1:4, 2:3}) # False (4 is value, not key)\nprint(1 in {1,2,3}) # True", - "week": 2 + "week": 2, + "snippet_id": "item:ks-4b427a2425", + "snippet_label": "Conditions" }, { "item_id": "ks-c19999c074", @@ -2997,7 +3551,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Conditional statements and expressions\nif/elif/else. One if at start, at most one else at end, unlimited elif in between. Indentation is critical — all code in a block must have same indentation. Conditional expression (ternary): value_if_true if condition else value_if_false.\nif/elif/else structure\nif condition_1:\n expression_1\nelif condition_2:\n expression_2\n expression_3\nelse:\n expression_4\nConditional expression (ternary)\n# Statement form:\nif a > 0:\n b = a\nelse:\n b = 0\n# Expression form:\nb = a if a > 0 else 0\n# Even simpler:\nb = max(0, a)", - "week": 2 + "week": 2, + "snippet_id": "item:ks-c19999c074", + "snippet_label": "Conditions" }, { "item_id": "cs-curated-hw-conditions-first-match-wins", @@ -3009,7 +3565,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Branch order matters because the first matching condition wins\nx = [5, 10, 15, 20]\na, b, c, d = 4, 9, 13, 15\nresult = []\nfor element in x:\n if element <= d:\n label = 'cat4'\n elif element >= c:\n label = 'cat3'\n elif element < b:\n label = 'cat2'\n elif element > a:\n label = 'cat1'\n else:\n label = 'catunknown'\n result.append(label)\nprint(result)\n['cat4', 'cat4', 'cat4', 'cat3']", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-conditions-first-match-wins", + "snippet_label": "Conditions" }, { "item_id": "manual-loop-translate", @@ -3021,7 +3579,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Translate `alphabet[1::2]` into a loop that collects every second character starting at index 1.\nInitialize an empty result, loop over the needed indices, and append the selected characters in order.\nresult = ''\nfor i in range(1, len(alphabet), 2):\n result += alphabet[i]", - "week": 2 + "week": 2, + "snippet_id": "item:manual-loop-translate", + "snippet_label": "Loops" }, { "item_id": "manual-break-continue", @@ -3033,7 +3593,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What is the difference between `break` and `continue` inside a loop?\n`break` exits the loop immediately; `continue` skips the rest of the current iteration and moves to the next one.\nfor x in data:\n if x < 0:\n continue\n if x == 0:\n break", - "week": 2 + "week": 2, + "snippet_id": "item:manual-break-continue", + "snippet_label": "Loops" }, { "item_id": "manual-enumerate-zip", @@ -3045,7 +3607,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "When do you reach for `enumerate` versus `zip`?\nUse `enumerate(seq)` when you need index and value together; use `zip(a, b)` when you need items from multiple iterables in parallel.\nfor i, value in enumerate(seq):\n ...\nfor left, right in zip(a, b):\n ...", - "week": 2 + "week": 2, + "snippet_id": "item:manual-enumerate-zip", + "snippet_label": "Loops" }, { "item_id": "kp-manual-loop-core", @@ -3057,7 +3621,23 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use `for` when you already have an iterable; use `while` when repetition should continue only while a condition stays `True`.", - "week": 2 + "week": 2, + "snippet_id": "item:kp-manual-loop-core", + "snippet_label": "Loops" + }, + { + "item_id": "kp-manual-loop-core-d1", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Pick the loop shape first\nPattern | Use when | Common exam note\nfor item in seq | you need the values | prefer this over indexing when position is irrelevant\nfor i, item in enumerate(seq, start) | you need both index and value | start defaults to 0\nwhile items: | truthiness controls repetition | stops when the list becomes empty\nfor _ in range(n) | repeat n times only | _ means the loop variable itself is unused", + "week": 2, + "snippet_id": "item:kp-manual-loop-core-d1", + "snippet_label": "Loops" }, { "item_id": "kp-manual-break-continue", @@ -3069,7 +3649,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`break` exits the loop immediately; `continue` skips the rest of the current iteration and moves to the next one.", - "week": 2 + "week": 2, + "snippet_id": "item:kp-manual-break-continue", + "snippet_label": "Loops" }, { "item_id": "kp-manual-enumerate", @@ -3081,7 +3663,23 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`enumerate(seq, start)` gives `(index, value)` pairs; `zip(a, b)` gives tuples of items from multiple iterables in parallel.", - "week": 2 + "week": 2, + "snippet_id": "item:kp-manual-enumerate", + "snippet_label": "Loops" + }, + { + "item_id": "kp-manual-enumerate-d1", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Start offset and tuple unpacking\nletters = ['a', 'b', 'c']\nfor index, letter in enumerate(letters, start=1):\n print(index, letter)\nfor left, right in zip(['x', 'y'], [10, 20]):\n print(left, right)", + "week": 2, + "snippet_id": "item:kp-manual-enumerate-d1", + "snippet_label": "Loops" }, { "item_id": "kp-manual-while-truthy", @@ -3093,7 +3691,37 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "A `while` condition is checked before every iteration, so a list loop like `while items:` keeps going only while the list is non-empty.", - "week": 2 + "week": 2, + "snippet_id": "item:kp-manual-while-truthy", + "snippet_label": "Loops" + }, + { + "item_id": "kp-iteration-traps", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`zip` stops at the shortest iterable, `in` checks membership, `//` floors division, `%` gives the remainder, and `sum(condition for ...)` counts how many times the condition is true.", + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" + }, + { + "item_id": "kp-iteration-traps-d1", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Iteration helpers and operator traps\nPattern | Returns / does | Trap\nzip(a, b) | pairs items in parallel | extra items in the longer iterable are ignored\nx in d | checks dict keys | not dict values\na // b | floor division | 7 // 2 is 3, not 3.5\na % b | remainder | use with // to reconstruct quotient + remainder\nsum(value > 0 for value in nums) | counts truths | True acts like 1 and False like 0", + "week": 2, + "snippet_id": "item:kp-iteration-traps-d1", + "snippet_label": "Loops" }, { "item_id": "ai-example-2", @@ -3105,7 +3733,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Skip certain values with `continue`\ntotal = 0\nfor number in [1, 2, '3', 3, 5, 7]:\n if type(number) == str:\n continue\n total += number\nprint(total) # 18\nUse `continue` to ignore the current item and jump straight to the next iteration.\n18", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" }, { "item_id": "ai-example-3", @@ -3117,7 +3747,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Loop variable not used — use _\nfor _ in range(5):\n print('Hello') # prints Hello 5 times\nUse `_` when the loop should repeat a fixed number of times but the loop variable itself is not needed.\nHello\nHello\nHello\nHello\nHello", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" }, { "item_id": "ai-example-4", @@ -3129,7 +3761,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`enumerate(seq, start=1)`\ncountries = ['Andorra', 'Belgium']\nfor index, country in enumerate(countries, 1):\n print(country, 'has index:', index)\n# Andorra has index: 1\n# Belgium has index: 2\nUse `enumerate` when you need both index and value, and set `start=1` if the numbering should begin at 1.\nAndorra has index: 1\nBelgium has index: 2", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" }, { "item_id": "ai-example-5", @@ -3141,7 +3775,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`zip(a, b)` pairs items in parallel\ncountries = ['Andorra', 'Belgium']\ncapitals = ['Andorra la Vella', 'Brussels']\nfor country, capital in zip(countries, capitals):\n print(country, 'has capital:', capital)\nUse `zip` when two sequences should be processed position by position together.\nAndorra has capital: Andorra la Vella\nBelgium has capital: Brussels", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" }, { "item_id": "ai-example-7", @@ -3153,7 +3789,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`while items:` repeats until the list is empty\nl1 = [1, 2, 3, 4, 5, 6]\ntotal = 0\nwhile l1: # truthy while list is non-empty\n total += l1[0]\n del l1[0]\nprint(total) # 21\nNon-empty lists are truthy and empty lists are falsy, so `while items:` is a common consume-until-empty loop.\n21", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" }, { "item_id": "manual-loop-max-sublist-sum", @@ -3165,7 +3803,23 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Keep the sub-list whose elements have the largest sum\nlists = [[1, 2], [4, 4], [3, 3, 1]]\nbest = lists[0]\nfor current in lists[1:]:\n if sum(current) > sum(best):\n best = current\nprint(best)\nStore the current best sub-list, compare `sum(current)` with `sum(best)` on each iteration, and update the winner when you find a larger total.\n[4, 4]", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" + }, + { + "item_id": "manual-loop-zip-enumerate-membership", + "card_id": "w2-loops", + "topic": "Loops", + "subtopic_id": "w2-loops-core", + "subtopic_title": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Combine `zip`, `enumerate`, unpacking, and membership\nnames = ['Ada', 'Bob', 'Cleo']\nscores = [8, 5]\nfor index, (name, score) in enumerate(zip(names, scores), start=1):\n passed = score in {5, 6, 7, 8, 9, 10}\n print(index, name, passed)\n`zip` stops at the shortest iterable, tuple unpacking works directly in the loop header, and `in` is often the clearest membership test.\n1 Ada True\n2 Bob True", + "week": 2, + "snippet_id": "subtopic:w2-loops:w2-loops-core", + "snippet_label": "for, while, Dictionary Iteration, enumerate(), zip(), and Walrus" }, { "item_id": "exam-intro_python_sample_final_24_25-14-w2-loops", @@ -3177,7 +3831,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Choose the program that iterates over integers from 1 to 10 and prints the sum of the current and previous number (starting with 0 as previous).\nA\nB\nC\nD\nB\nOption B correctly updates the 'previous' state at the end of each iteration to match the logic of the target output.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-intro_python_sample_final_24_25-14-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", @@ -3189,7 +3845,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted strings to the list, resulting in 10 elements.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2023-2-w2-loops", @@ -3201,7 +3859,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What is the output of the following code snippet?", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-2-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2024-3-w2-loops", @@ -3213,7 +3873,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 != 0:\nprint(i)\nD x = '12345'\nfor i in x:\nif i % 2 != 0:\nprint(i)", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-trial_midterm-5-w2-loops", @@ -3225,7 +3887,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 != 0:\nprint(i)\nC x = '12345'\nfor i in x:\nif i % 2 != 0:\nprint(i)\nD for i in range(7, 1, -2):\nprint(i)", - "week": 2 + "week": 2, + "snippet_id": "item:exam-trial_midterm-5-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2023-14-w2-loops", @@ -3237,7 +3901,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the sorting order of the elements in a list.\nA values = []\nfor index, value in enumerate(alphabet, start=1):\nif index % 2 == 0:\nvalues.append(value)\nprint(values)\nB values = []\nfor index, value in enumerate(alphabet[::-1]):\nif index % 2 == 0:\nvalues.append(value)\nvalues.reverse()\nprint(values)\nC Both of the given options.\nD None of the given options.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops" }, { "item_id": "ks-72c9eada91", @@ -3249,7 +3915,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Augmented assignment operators\nShorthand for a = a OP b. All arithmetic operators have an augmented form.\nAll augmented operators\na += 1 # a = a + 1\na -= 2 # a = a - 2\na *= 3 # a = a * 3\na /= 4 # a = a / 4\na //= 5 # a = a // 5\na %= 6 # a = a % 6", - "week": 2 + "week": 2, + "snippet_id": "item:ks-72c9eada91", + "snippet_label": "Loops" }, { "item_id": "ks-bddafc66a0", @@ -3261,7 +3929,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "For-loops\nfor variable in sequence: expression. break: exit loop entirely. continue: skip to next iteration. You don't have to use the loop variable; use _ as convention when not needed.\nFor-loop with continue\ntotal = 0\nfor number in [1, 2, '3', 3, 5, 7]:\n if type(number) == str:\n continue\n total += number\nprint(total) # 18\nLoop variable not used — use _\nfor _ in range(5):\n print('Hello') # prints Hello 5 times", - "week": 2 + "week": 2, + "snippet_id": "item:ks-bddafc66a0", + "snippet_label": "Loops" }, { "item_id": "ks-59aaf6b0ee", @@ -3273,7 +3943,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "enumerate()\nProvides index alongside value when looping. enumerate(seq, start) — second arg sets the start index (default 0).\nenumerate with start=1\ncountries = ['Andorra', 'Belgium']\nfor index, country in enumerate(countries, 1):\n print(country, 'has index:', index)\n# Andorra has index: 1\n# Belgium has index: 2", - "week": 2 + "week": 2, + "snippet_id": "item:ks-59aaf6b0ee", + "snippet_label": "Loops" }, { "item_id": "ks-4c6274845e", @@ -3285,7 +3957,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "zip()\nLoops over multiple sequences in parallel. Zips sequences of equal length (Python handles unequal lengths but it can be messy). Can zip sequences of different types. Can zip more than 2.\nzip two lists\ncountries = ['Andorra', 'Belgium']\ncapitals = ['Andorra la Vella', 'Brussels']\nfor country, capital in zip(countries, capitals):\n print(country, 'has capital:', capital)", - "week": 2 + "week": 2, + "snippet_id": "item:ks-4c6274845e", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2024-9-w2-loops", @@ -3297,7 +3971,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-9-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2024-17-w2-loops", @@ -3309,7 +3985,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following function which take a list of numerical strings as an argument.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-17-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2024-18-w2-loops", @@ -3321,7 +3999,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor char in key:\nif char == character:\ncount += 1\ny[key] = count\nreturn y\nWhat would be returned by this function, if we call the function twice as follows:\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'], 'i')\ncount_character(['Emma', 'Julia', 'Ian', 'Noah', 'Liam', 'Anna'])\nA {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 1, 'Julia': 1, 'Ian': 1, 'Noah': 1, 'Liam': 1, 'Anna': 1}\nB {'Emma': 0, 'Julia': 1, 'Ian': 0, 'Noah': 0, 'Liam': 1, 'Anna': 0}\n{'Emma': 0, 'Julia': 0, 'Ian': 0, 'Noah': 0, 'Liam': 0, 'Anna': 0}\nC The first function call will result in an error because there are too many arguments.\nD The second function call will result in an error because there is a missing argument.", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2024-20-w2-loops", @@ -3333,7 +4013,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "What is the output of the program below?", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-20-w2-loops", + "snippet_label": "Loops" }, { "item_id": "exam-midterm_2024-21-w2-loops", @@ -3345,7 +4027,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?", - "week": 2 + "week": 2, + "snippet_id": "item:exam-midterm_2024-21-w2-loops", + "snippet_label": "Loops" }, { "item_id": "ks-8ad541fef7", @@ -3357,7 +4041,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "While-loops\nwhile condition: expression. Checks condition BEFORE each execution. Use break and continue. Watch for infinite loops (Ctrl+C to exit). Use when you don't know beforehand how many iterations are needed. For-loops can always be replaced by while-loops.\nWhile with break/continue\ntotal = 0\nwhile True:\n number = int(input('give a number, or 100 to stop '))\n if number == 100:\n break\n if number % 2 == 0:\n continue\n total += number\nprint(total)\nTruthy/Falsy in while condition\nl1 = [1, 2, 3, 4, 5, 6]\ntotal = 0\nwhile l1: # truthy while list is non-empty\n total += l1[0]\n del l1[0]\nprint(total) # 21", - "week": 2 + "week": 2, + "snippet_id": "item:ks-8ad541fef7", + "snippet_label": "Loops" }, { "item_id": "ks-624034d573", @@ -3369,7 +4055,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Walrus operator :=\nIntroduced in Python 3.8. Assigns AND evaluates to a value (unlike = which is a statement). Useful in while conditions to assign and test at once.\nWalrus in while loop\ntotal = 0\nwhile (number := int(input('give a number, or 100 to stop '))) != 100:\n if number % 2 == 1:\n total += number\nprint(total)", - "week": 2 + "week": 2, + "snippet_id": "item:ks-624034d573", + "snippet_label": "Loops" }, { "item_id": "cs-curated-hw-loops-enumerate-mark-max", @@ -3381,7 +4069,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Use enumerate() to keep indices while relabeling one special case\nx = [65, 43, 1, 0, 59, 16, 86, 40, 60]\nmax_value = max(x)\nresult = {}\nfor index, value in enumerate(x):\n key = 'highest' if value == max_value else index\n result[key] = value\nprint(result)\n{0: 65, 1: 43, 2: 1, 3: 0, 4: 59, 5: 16, 'highest': 86, 7: 40, 8: 60}", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-loops-enumerate-mark-max", + "snippet_label": "Loops" }, { "item_id": "cs-curated-hw-loops-zip-filter-pairs", @@ -3393,7 +4083,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "zip() aligns two lists so you can filter pairs into a dict\nkeys = [3, 2, 1, 4]\nvalues = [3, 37, 60, 79]\nresult = {}\nfor key, value in zip(keys, values):\n if key != value and value % 5:\n result[key] = value\nprint(result)\n{2: 37, 4: 79}", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-loops-zip-filter-pairs", + "snippet_label": "Loops" }, { "item_id": "cs-curated-hw-loops-market-clearing", @@ -3405,7 +4097,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Flatten, sort, and zip demand/supply curves to count trades\nbuyers = {'buyer1': [24, 16, 13, 6, 5], 'buyer2': [23, 21, 19, 10, 7], 'buyer3': [21, 20, 15, 13, 10], 'buyer4': [20, 17, 9, 6, 5]}\nsellers = {'seller1': [8, 10, 14, 19, 21], 'seller2': [6, 13, 16, 21, 23], 'seller3': [8, 12, 13, 22, 23], 'seller4': [8, 9, 13, 21, 24]}\ndemand = []\nfor buyer_values in buyers.values():\n demand += buyer_values\nsupply = []\nfor seller_values in sellers.values():\n supply += seller_values\nquantity_sold = 0\nfor bid, ask in zip(sorted(demand, reverse=True), sorted(supply)):\n if bid >= ask:\n quantity_sold += 1\nprint(quantity_sold)\n10", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-loops-market-clearing", + "snippet_label": "Loops" }, { "item_id": "cs-curated-hw-loops-nested-pairwise-dict", @@ -3417,7 +4111,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Nested loops can build pairwise results for every combination\ndef main(minimum, maximum):\n result = {}\n for first in range(minimum, maximum + 1):\n for second in range(minimum, maximum + 1):\n result[(first, second)] = first - second\n return result\n\nprint(main(2, 4))\n{(2, 2): 0, (2, 3): -1, (2, 4): -2, (3, 2): 1, (3, 3): 0, (3, 4): -1, (4, 2): 2, (4, 3): 1, (4, 4): 0}", - "week": 2 + "week": 2, + "snippet_id": "item:cs-curated-hw-loops-nested-pairwise-dict", + "snippet_label": "Loops" }, { "item_id": "kp-1", @@ -3429,7 +4125,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "In conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers).", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "kp-1-d1", @@ -3441,7 +4139,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Falsy values\n# All evaluate to False in a condition:\n[] # empty list\n() # empty tuple\n{} # empty dict\nset() # empty set\n'' # empty string\n0 # zero int\n0.0 # zero float", - "week": 2 + "week": 2, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Conversion and Truthiness" }, { "item_id": "kp-2", @@ -3453,7 +4153,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Python requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "kp-2-d1", @@ -3465,7 +4167,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Explicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\nprint(int('1a')) # ERROR\nprint(float('1') == 1.0) # True\nprint(float('1.0') == 1.0) # True\nprint(tuple([1,2,3]) == (1,2,3)) # True\nprint(tuple({1:3, 2:4}) == (1,2)) # True (dict->tuple gives keys)\nprint(list(range(1,5,2)) == [1,3]) # True\nprint(dict([1, 2])) # ERROR\nprint(dict([(1,3),(2,4)]) == {1:3, 2:4}) # True", - "week": 2 + "week": 2, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Conversion and Truthiness" }, { "item_id": "kp-2-d2", @@ -3477,7 +4181,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Implicit conversion (Python allows with bool/numeric mix)\nprint(1 + True) # 2\nprint(1.0 + False) # 1.0\nprint('1' * 2) # '11'\nprint('1' * True) # '1'\nprint('1' * False) # ''", - "week": 2 + "week": 2, + "snippet_id": "item:kp-2-d2", + "snippet_label": "Conversion and Truthiness" }, { "item_id": "ai-example-1", @@ -3489,7 +4195,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Falsy values\n# All evaluate to False in a condition:\n[] # empty list\n() # empty tuple\n{} # empty dict\nset() # empty set\n'' # empty string\n0 # zero int\n0.0 # zero float\nIn conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers).", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ai-example-2", @@ -3501,7 +4209,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Explicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\nprint(int('1a')) # ERROR\nprint(float('1') == 1.0) # True\nprint(float('1.0') == 1.0) # True\nprint(tuple([1,2,3]) == (1,2,3)) # True\nprint(tuple({1:3, 2:4}) == (1,2)) # True (dict->tuple gives keys)\nprint(list(range(1,5,2)) == [1,3]) # True\nprint(dict([1, 2])) # ERROR\nprint(dict([(1,3),(2,4)]) == {1:3, 2:4}) # True\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ai-example-3", @@ -3513,7 +4223,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Implicit conversion (Python allows with bool/numeric mix)\nprint(1 + True) # 2\nprint(1.0 + False) # 1.0\nprint('1' * 2) # '11'\nprint('1' * True) # '1'\nprint('1' * False) # ''\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ai-example-4", @@ -3525,7 +4237,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "str(1) versus int('1')\nprint(str(1) == '1')\nprint(int('1') == 1)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ai-example-5", @@ -3537,7 +4251,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Why `'1' + 2` raises `TypeError`\ntry:\n print ('1' + 2)\nexcept Exception as e:\n print(e)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ai-example-6", @@ -3549,7 +4265,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Why `dict([1, 2])` raises `ValueError`\ntry:\n print(dict([1, 2]))\nexcept Exception as e:\n print(e)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ai-example-7", @@ -3561,7 +4279,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Why `int('1a')` raises `ValueError`\ntry:\n print(int('1a') == 1)\nexcept Exception as e:\n print(e)", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ai-example-8", @@ -3573,7 +4293,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Truthy list in a `while` condition\nl1 = [1, 2, 3, 4, 5, 6]\ntotal = 0\nwhile l1:\n total += l1[0]\n del l1[0]\nprint(total)\nFor numeric variables, `a += 1` updates the stored value the same way as `a = a + 1`.", - "week": 2 + "week": 2, + "snippet_id": "subtopic:w2-conversion-and-truthiness:w2-conversion-and-truthiness-core", + "snippet_label": "Explicit Conversion and Truthy/Falsy Rules" }, { "item_id": "ks-d7e6d1b5b5", @@ -3585,7 +4307,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Truthy and Falsy\nIn conditions, Python auto-converts to bool. Falsy: [], (), {}, set(), '', 0, 0.0, range(0), None. Truthy: everything else (non-empty collections, non-zero numbers).\nFalsy values\n# All evaluate to False in a condition:\n[] # empty list\n() # empty tuple\n{} # empty dict\nset() # empty set\n'' # empty string\n0 # zero int\n0.0 # zero float", - "week": 2 + "week": 2, + "snippet_id": "item:ks-d7e6d1b5b5", + "snippet_label": "Conversion and Truthiness" }, { "item_id": "ks-d9760d8cd8", @@ -3597,7 +4321,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Type conversion (explicit)\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().\nExplicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\nprint(int('1a')) # ERROR\nprint(float('1') == 1.0) # True\nprint(float('1.0') == 1.0) # True\nprint(tuple([1,2,3]) == (1,2,3)) # True\nprint(tuple({1:3, 2:4}) == (1,2)) # True (dict->tuple gives keys)\nprint(list(range(1,5,2)) == [1,3]) # True\nprint(dict([1, 2])) # ERROR\nprint(dict([(1,3),(2,4)]) == {1:3, 2:4}) # True\nImplicit conversion (Python allows with bool/numeric mix)\nprint(1 + True) # 2\nprint(1.0 + False) # 1.0\nprint('1' * 2) # '11'\nprint('1' * True) # '1'\nprint('1' * False) # ''", - "week": 2 + "week": 2, + "snippet_id": "item:ks-d9760d8cd8", + "snippet_label": "Conversion and Truthiness" }, { "item_id": "cs-fc8bdeb969", @@ -3609,7 +4335,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "type_conversion\nprint (1==1.0, 1.0 == True, 0 == False)", - "week": 2 + "week": 2, + "snippet_id": "item:cs-fc8bdeb969", + "snippet_label": "Conversion and Truthiness" }, { "item_id": "cs-3e39a2f12f", @@ -3621,7 +4349,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "type_conversion\nprint ('1' * 2, '1' * True, '1' * False)", - "week": 2 + "week": 2, + "snippet_id": "item:cs-3e39a2f12f", + "snippet_label": "Conversion and Truthiness" }, { "item_id": "manual-call-vs-index", @@ -3633,7 +4363,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What error do you get from `print[1]` and from `[1, 2, 3](0)`?\n`print[1]` tries to subscript a function, while `[1, 2, 3](0)` tries to call a list. Both raise `TypeError`, but for opposite reasons.\nprint[1]\n[1, 2, 3](0)", - "week": 3 + "week": 3, + "snippet_id": "item:manual-call-vs-index", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "manual-string-return-shape", @@ -3645,7 +4377,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do you recognize that a function should `return` a string instead of `print` it?\nIf the result must be reused later, the function should `return` the string so the caller can store, combine, or print it afterwards.\ndef get_tld(url):\n parts = url.split('.')\n return parts[-1].split('/')[0]", - "week": 3 + "week": 3, + "snippet_id": "item:manual-string-return-shape", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "manual-list-of-dicts-loop", @@ -3657,7 +4391,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do you access values when looping over a list of dictionaries?\nEach loop iteration gives one dictionary, so read fields with keys like `student['Name']` and `student['Grade']`.\nfor student in students:\n print(student['Name'], student['Grade'])", - "week": 3 + "week": 3, + "snippet_id": "item:manual-list-of-dicts-loop", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "kp-1", @@ -3669,7 +4405,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Define with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a list and raises `TypeError`.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "snippet_label": "def, Calls, and Methods vs Functions" }, { "item_id": "kp-1-d1", @@ -3681,7 +4419,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Basic function\ndef adder(n1, n2):\n total = n1 + n2\n return total\na = adder(1, 2)\nprint(a) # 3", - "week": 3 + "week": 3, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "kp-1-d2", @@ -3693,7 +4433,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Wrong bracket errors\nprint[1] # TypeError: 'function' object is not subscriptable\nl1 = [1,2,3]\nl1(1) # TypeError: 'list' object is not callable", - "week": 3 + "week": 3, + "snippet_id": "item:kp-1-d2", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "kp-2", @@ -3705,7 +4447,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Methods are functions attached to objects. Some mutate the object in place, while others return a value; string methods always return a new string.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "snippet_label": "def, Calls, and Methods vs Functions" }, { "item_id": "kp-2-d1", @@ -3717,7 +4461,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Method on immutable — must capture return value\ns1 = 'UVA Amsterdam'\ns1 = s1.upper() # CORRECT — captures new string\ns1.upper() # WRONG — result is lost, s1 unchanged", - "week": 3 + "week": 3, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "kp-2-d2", @@ -3729,7 +4475,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Method on mutable — changes in place vs returns value\nl1 = [3, 1, 2]\nl1.sort() # changes l1 in place, returns None\nprint(l1) # [1, 2, 3]\nprint(l1.index(2)) # 1 (returns index, doesn't change l1)", - "week": 3 + "week": 3, + "snippet_id": "item:kp-2-d2", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "kp-3", @@ -3741,7 +4489,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Function skeleton: `def f(x): return result`. Define with `def ...`, call with `()`, and use `[]` only for indexing.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "snippet_label": "def, Calls, and Methods vs Functions" }, { "item_id": "ai-example-1", @@ -3753,7 +4503,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Define, call, and return a value\ndef adder(n1, n2):\n total = n1 + n2\n return total\na = adder(1, 2)\nprint(a) # 3\nDefine with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a list and raises `TypeError`.\n3", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "snippet_label": "def, Calls, and Methods vs Functions" }, { "item_id": "ai-example-2", @@ -3765,7 +4517,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Wrong bracket errors\nprint[1] # TypeError: 'function' object is not subscriptable\nl1 = [1,2,3]\nl1(1) # TypeError: 'list' object is not callable\nDefine with `def name(params):` and call with `()`. `f[3]` tries to index, while `lst(0)` tries to call a list and raises `TypeError`.\nTypeError\nTypeError", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "snippet_label": "def, Calls, and Methods vs Functions" }, { "item_id": "ai-example-3", @@ -3777,7 +4531,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Method on immutable — must capture return value\ns1 = 'UVA Amsterdam'\ns1 = s1.upper() # CORRECT — captures new string\ns1.upper() # WRONG — result is lost, s1 unchanged\nMethods are functions attached to objects. Some mutate the object in place, while others return a value; string methods always return a new string.\nUVA AMSTERDAM", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "snippet_label": "def, Calls, and Methods vs Functions" }, { "item_id": "ai-example-4", @@ -3788,8 +4544,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Method on mutable — changes in place vs returns value\nl1 = [3, 1, 2]\nl1.sort() # changes l1 in place, returns None\nprint(l1) # [1, 2, 3]\nprint(l1.index(2)) # 1 (returns index, doesn't change l1)\nMethods are functions attached to objects. Some mutate the object in place, while others return a value; string methods always return a new string.\n[1, 2, 3]\n1", - "week": 3 + "search_text": "`list.sort()` mutates in place and returns `None`\nl1 = [3, 1, 2]\nl1.sort() # changes l1 in place, returns None\nprint(l1) # [1, 2, 3]\nprint(l1.index(2)) # 1 (returns index, doesn't change l1)\nMutating methods and value-returning methods look similar at a glance, so keep the exam distinction clear: `sort()` changes the list, while `index()` returns information about it.\n[1, 2, 3]\n1", + "week": 3, + "snippet_id": "subtopic:w3-defining-and-calling-functions:w3-defining-and-calling-functions-core", + "snippet_label": "def, Calls, and Methods vs Functions" }, { "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", @@ -3801,7 +4559,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following code segments will achieve what you want?\nA\nB\nC\nD\nA\nWhen iterating over a list of dictionaries, each iteration yields a dictionary. You access values using keys like student['Name']. Options B and D fail because lists do not have an .items() method.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", @@ -3813,7 +4573,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which of the following code lines will create a dictionary, in which the keys are the elements of list_1 and the values are the number of characters in the corresponding key?\nA\nB\nC\nD\nA\nThis is a standard dictionary comprehension. Option B is a list comprehension, Option C is a set comprehension, and Option D swaps keys and values.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-intro_python_sample_final_24_25-11-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", @@ -3825,7 +4587,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What will be printed by the function calls in the main function provided?\nA\nB\nC\nD\nD\nThe function checks if all elements in the input list are either all empty or all non-empty. For the sets and lists provided, they are consistent within each call.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-intro_python_sample_final_24_25-17-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", @@ -3837,7 +4601,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?\na\nb\nc\nd\na\nOption A splits the entire URL by '.', so the last element will be 'html' (from 'bachelors.html'). Then splitting 'html' by '/' and taking the first element still results in 'html', not the top-level domain 'nl'. Therefore, it does NOT achieve what is intended.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", @@ -3849,7 +4615,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) at various places.\n\nFor example, the following function calls:\nformat_phone_number(\"020-525-1400\")\nformat_phone_number(\"020-5251400\")\nformat_phone_number(\"020-525-14-00\")\nshould all return the string:\n\"0205251400\"\n\nWhich of the following code segments does not achieve what you want?\na\nb\nc\nd\na\nStrings in Python are immutable. The `replace()` method returns a new string, it does not modify the original string in place. Because Option A does not reassign the result of `number.replace(\"-\", \"\")` or return it directly, it returns the original, unmodified string.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", @@ -3861,7 +4629,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?\na\nb\nc\nd\na\nOption A correctly removes spaces, converts strings to lower case, transforms them to lists, and sorts the lists using sorted() before comparing them. Option B is incorrect because strings do not have a .sort() method. Option C is incorrect because list.sort() operates in-place and returns None, so it would compare None == None. Option D is incorrect because sorted() returns a list, and lists do not have a .replace() or .lower() method.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "ks-e09d7f145b", @@ -3873,7 +4643,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Function definition and calling\ndef keyword, function name, parameters in parentheses, colon, indented body. Call with round brackets (). Using [] gives TypeError 'not subscriptable'. Using [] on a list with () gives TypeError 'not callable'.\nBasic function\ndef adder(n1, n2):\n total = n1 + n2\n return total\na = adder(1, 2)\nprint(a) # 3\nWrong bracket errors\nprint[1] # TypeError: 'function' object is not subscriptable\nl1 = [1,2,3]\nl1(1) # TypeError: 'list' object is not callable", - "week": 3 + "week": 3, + "snippet_id": "item:ks-e09d7f145b", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "ks-ab66f3bab6", @@ -3885,7 +4657,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Methods vs functions\nMethods are functions attached to objects. Calling obj.method() is equivalent to Class.method(obj). For mutable objects: some methods CHANGE the object (e.g. list.sort()), some RETURN a value (e.g. list.index()). For immutable objects: methods always return a new value (can't change the object itself). COMMON ERROR: s1.upper() on strings — you must do s1 = s1.upper() to save the result.\nMethod on immutable — must capture return value\ns1 = 'UVA Amsterdam'\ns1 = s1.upper() # CORRECT — captures new string\ns1.upper() # WRONG — result is lost, s1 unchanged\nMethod on mutable — changes in place vs returns value\nl1 = [3, 1, 2]\nl1.sort() # changes l1 in place, returns None\nprint(l1) # [1, 2, 3]\nprint(l1.index(2)) # 1 (returns index, doesn't change l1)", - "week": 3 + "week": 3, + "snippet_id": "item:ks-ab66f3bab6", + "snippet_label": "Defining and Calling Functions" }, { "item_id": "aiq-1", @@ -3897,7 +4671,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Condition flow and branch result\nExam • midterm_2024 • Q1\nConsider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-1", + "snippet_label": "Return Behavior" }, { "item_id": "aiq-2", @@ -3909,7 +4685,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-2", + "snippet_label": "Return Behavior" }, { "item_id": "aiq-3", @@ -3921,7 +4699,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. Correct: d.\nExam • extra_practice • Q9", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-3", + "snippet_label": "Return Behavior" }, { "item_id": "aiq-4", @@ -3933,7 +4713,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None.", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-4", + "snippet_label": "Return Behavior" }, { "item_id": "aiq-5", @@ -3945,7 +4727,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-5", + "snippet_label": "Return Behavior" }, { "item_id": "kp-1", @@ -3957,7 +4741,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Returns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "kp-1-d1", @@ -3969,7 +4755,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Returning a tuple (multiple values)\ndef powers(n1):\n return n1 ** 2, n1 ** 3 # returns a tuple\npower2, power3 = powers(3)\nprint(power2, power3) # 9 27", - "week": 3 + "week": 3, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Return Behavior" }, { "item_id": "kp-2", @@ -3981,7 +4769,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "If a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None:", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "kp-2-d1", @@ -3993,7 +4783,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Implicit None return\ndef adder(n1, n2):\n if type(n1) == type(n2) == int:\n total = n1 + n2\n return total\na = adder('1', 2) # Returns None (no return hit)\nprint(a) # None", - "week": 3 + "week": 3, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Return Behavior" }, { "item_id": "kp-3", @@ -4005,7 +4797,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "(1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "kp-3-d1", @@ -4017,7 +4811,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "1-element tuple gotcha\nt1 = (1)\nprint(type(t1) == tuple) # False\nprint(type(t1) == int) # True\nt1 = (1,) # correct 1-element tuple\nt1 = 1, # also correct\nx, y = y, x # swap using tuple unpacking", - "week": 3 + "week": 3, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Return Behavior" }, { "item_id": "kp-4", @@ -4029,7 +4825,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Does nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "kp-4-d1", @@ -4041,7 +4839,37 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "pass as stub\ndef adder(n1, n2):\n if type(n1) == int and type(n2) == int:\n result = n1 + n2\n else:\n pass # placeholder — won't cause IndentationError\n return result", - "week": 3 + "week": 3, + "snippet_id": "item:kp-4-d1", + "snippet_label": "Return Behavior" + }, + { + "item_id": "kp-manual-mutating-methods-none", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "w3-return-behavior-core", + "subtopic_title": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A missing `return` is not the only source of `None`: many mutating methods also return `None`. Keep the mutated object, not the method call result.", + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" + }, + { + "item_id": "kp-manual-mutating-methods-none-d1", + "card_id": "w3-return-behavior", + "topic": "Return Behavior", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Common `None` traps\nCode | What comes back\nfunction with no `return` hit | None\nl1.sort() | None\nl1.append(x) | None\ns.upper() | new string", + "week": 3, + "snippet_id": "item:kp-manual-mutating-methods-none-d1", + "snippet_label": "Return Behavior" }, { "item_id": "ai-example-1", @@ -4053,7 +4881,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Returning a tuple (multiple values)\ndef powers(n1):\n return n1 ** 2, n1 ** 3 # returns a tuple\npower2, power3 = powers(3)\nprint(power2, power3) # 9 27\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "ai-example-2", @@ -4065,7 +4895,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Implicit None return\ndef adder(n1, n2):\n if type(n1) == type(n2) == int:\n total = n1 + n2\n return total\na = adder('1', 2) # Returns None (no return hit)\nprint(a) # None\nIf a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None:", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "ai-example-3", @@ -4077,7 +4909,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "1-element tuple gotcha\nt1 = (1)\nprint(type(t1) == tuple) # False\nprint(type(t1) == int) # True\nt1 = (1,) # correct 1-element tuple\nt1 = 1, # also correct\nx, y = y, x # swap using tuple unpacking\n(1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "ai-example-4", @@ -4088,8 +4922,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "pass as stub\ndef adder(n1, n2):\n if type(n1) == int and type(n2) == int:\n result = n1 + n2\n else:\n pass # placeholder — won't cause IndentationError\n return result\nDoes nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this.", - "week": 3 + "search_text": "Mutating method returns `None`\nl1 = [3, 1, 2]\nresult = l1.sort()\nprint(result)\nprint(l1)\nA missing `return` is not the only source of `None`: mutating methods such as `sort()` often change the object in place and return `None`.", + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "ai-example-5", @@ -4101,7 +4937,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Function return value and trace\ndef adder(n1, n2):\n return n1 + n2\na = adder(1,2)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "ai-example-6", @@ -4112,8 +4950,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Function return value and trace\ndef adder(n1, n2):\n total = n1 + n2\na = adder(1, 2)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", - "week": 3 + "search_text": "Computed a local variable but forgot to return it\ndef adder(n1, n2):\n total = n1 + n2\na = adder(1, 2)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "ai-example-7", @@ -4124,8 +4964,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Function return value and trace\ndef powers(n1):\n return n1 ** 2, n1 ** 3\na = powers(3)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", - "week": 3 + "search_text": "A tuple return stays one tuple value\ndef powers(n1):\n return n1 ** 2, n1 ** 3\na = powers(3)\nprint(a)\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "ai-example-8", @@ -4136,8 +4978,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Function return value and trace\ndef powers(n1):\n return n1 ** 2, n1 ** 3\npower2, power3 = powers(3)\nprint(power2, power3)\nTrace the returned value, not just what gets printed while the function runs.", - "week": 3 + "search_text": "Unpack a tuple return into multiple names\ndef powers(n1):\n return n1 ** 2, n1 ** 3\npower2, power3 = powers(3)\nprint(power2, power3)\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3, + "snippet_id": "subtopic:w3-return-behavior:w3-return-behavior-core", + "snippet_label": "return, Implicit None, Multiple Returns, pass, and Single-Element Tuples" }, { "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", @@ -4149,7 +4993,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior" }, { "item_id": "exam-Resit 22/23-3-w3-return-behavior", @@ -4161,7 +5007,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior" }, { "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", @@ -4173,7 +5021,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior" }, { "item_id": "exam-midterm_2024-1-w3-return-behavior", @@ -4185,7 +5035,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior" }, { "item_id": "exam-extra_practice-7-w3-return-behavior", @@ -4197,7 +5049,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "def multiply(num1, num2):\n\tglobal result\n\tresult = num1 * num2\n\nprint(multiply(2, 3))\nprint(result)\na\nb\nc\nd\nb\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-extra_practice-7-w3-return-behavior", + "snippet_label": "Return Behavior" }, { "item_id": "exam-extra_practice-9-w3-return-behavior", @@ -4209,7 +5063,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\nb\nc\nd\nd\na: *args creates a tuple, sum_even_in_list accepts any iterable so passing a tuple works. b: list comprehension on tuple works fine. c: direct iteration over tuple works. All three produce the same result. Correct: d.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior" }, { "item_id": "ks-00b2983ca8", @@ -4221,7 +5077,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Return statement\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.\nReturning a tuple (multiple values)\ndef powers(n1):\n return n1 ** 2, n1 ** 3 # returns a tuple\npower2, power3 = powers(3)\nprint(power2, power3) # 9 27", - "week": 3 + "week": 3, + "snippet_id": "item:ks-00b2983ca8", + "snippet_label": "Return Behavior" }, { "item_id": "ks-14515a5856", @@ -4233,7 +5091,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Implicit return — None\nIf a function reaches the end without a return statement, Python returns None automatically. This is bad practice but you must know it. Test with: if a != None: or if a is not None:\nImplicit None return\ndef adder(n1, n2):\n if type(n1) == type(n2) == int:\n total = n1 + n2\n return total\na = adder('1', 2) # Returns None (no return hit)\nprint(a) # None", - "week": 3 + "week": 3, + "snippet_id": "item:ks-14515a5856", + "snippet_label": "Return Behavior" }, { "item_id": "ks-d1a2d7739d", @@ -4245,7 +5105,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Single-element tuple\n(1) is NOT a tuple — it's just the integer 1. To create a 1-element tuple: t = (1,) or t = 1,. Neat swap trick: x, y = y, x\n1-element tuple gotcha\nt1 = (1)\nprint(type(t1) == tuple) # False\nprint(type(t1) == int) # True\nt1 = (1,) # correct 1-element tuple\nt1 = 1, # also correct\nx, y = y, x # swap using tuple unpacking", - "week": 3 + "week": 3, + "snippet_id": "item:ks-d1a2d7739d", + "snippet_label": "Return Behavior" }, { "item_id": "ks-db93da9e3e", @@ -4257,7 +5119,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "pass keyword\nDoes nothing. Used as a placeholder when an indented block is required but you have nothing to put there yet (stub). After a colon you must have an indented block — pass satisfies this.\npass as stub\ndef adder(n1, n2):\n if type(n1) == int and type(n2) == int:\n result = n1 + n2\n else:\n pass # placeholder — won't cause IndentationError\n return result", - "week": 3 + "week": 3, + "snippet_id": "item:ks-db93da9e3e", + "snippet_label": "Return Behavior" }, { "item_id": "manual-local-name", @@ -4269,7 +5133,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Why does `print(n1)` fail outside `def adder(n1, n2): ...`?\nParameter names are local to the function body, so they do not exist in the global scope after the call finishes.\ndef adder(n1, n2):\n return n1 + n2\n\nadder(1, 2)\nprint(n1)", - "week": 3 + "week": 3, + "snippet_id": "item:manual-local-name", + "snippet_label": "Scope" }, { "item_id": "manual-unboundlocal", @@ -4281,7 +5147,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Why can assigning to a name inside a function cause `UnboundLocalError`?\nIf a function assigns to a name anywhere in its body, Python treats that name as local throughout the function unless you declare it `global` or `nonlocal`.\nb = 1\n\ndef main(a):\n b = b\n return a", - "week": 3 + "week": 3, + "snippet_id": "item:manual-unboundlocal", + "snippet_label": "Scope" }, { "item_id": "manual-global", @@ -4293,7 +5161,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "When do you need `global`?\nUse `global name` only when the function should rebind a global variable; simple reads of a global name do not need it.\nn1 = 1\n\ndef changer():\n global n1\n n1 = n1 + 1", - "week": 3 + "week": 3, + "snippet_id": "item:manual-global", + "snippet_label": "Scope" }, { "item_id": "kp-manual-scope-local", @@ -4305,7 +5175,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Names assigned inside a function are local by default, including parameter names.", - "week": 3 + "week": 3, + "snippet_id": "item:kp-manual-scope-local", + "snippet_label": "Scope" }, { "item_id": "kp-manual-scope-unbound", @@ -4317,7 +5189,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "If a function assigns to a name anywhere, Python treats that name as local throughout that function unless `global` or `nonlocal` says otherwise.", - "week": 3 + "week": 3, + "snippet_id": "item:kp-manual-scope-unbound", + "snippet_label": "Scope" }, { "item_id": "kp-manual-scope-global", @@ -4329,7 +5203,23 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use `global x` only when the function should rebind the global name `x`; mutating an object passed in as an argument does not require `global`.", - "week": 3 + "week": 3, + "snippet_id": "item:kp-manual-scope-global", + "snippet_label": "Scope" + }, + { + "item_id": "kp-manual-scope-return-outside", + "card_id": "w3-scope", + "topic": "Scope", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A local variable disappears after the function ends. If you need that value outside the function, return it and assign the result in the caller.", + "week": 3, + "snippet_id": "item:kp-manual-scope-return-outside", + "snippet_label": "Scope" }, { "item_id": "manual-scope-local-name", @@ -4340,8 +5230,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Parameter names stay local to the function\ndef adder(n1, n2):\n return n1 + n2\n\nprint(adder(1, 2))\nprint(n1)\nAfter the function call, `n1` and `n2` do not exist outside the function body.\n3\nNameError", - "week": 3 + "search_text": "Local names disappear after the call\ndef adder(n1, n2):\n return n1 + n2\n\nprint(adder(1, 2))\nprint(n1)\nAfter the function call, `n1` and `n2` no longer exist outside the function body. Return the value if the caller needs to use it later.\n3\nNameError", + "week": 3, + "snippet_id": "subtopic:w3-scope:w3-scope-core", + "snippet_label": "Global vs Local Names and Scope Errors" }, { "item_id": "manual-scope-unbound", @@ -4353,7 +5245,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Assignment makes the name local\nb = 1\n\ndef main(a):\n b = b\n return a\n\nprint(main(1))\nBecause `b` is assigned inside `main`, Python treats it as local before the `b = b` line runs.\nUnboundLocalError", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-scope:w3-scope-core", + "snippet_label": "Global vs Local Names and Scope Errors" }, { "item_id": "manual-scope-global-change", @@ -4365,7 +5259,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Use `global` to rebind a global name\nn1 = 1\n\ndef changer():\n global n1\n n1 = n1 + 1\n\nchanger()\nprint(n1)\nWith `global n1`, the assignment updates the global name instead of creating a local one.\n2", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-scope:w3-scope-core", + "snippet_label": "Global vs Local Names and Scope Errors" }, { "item_id": "manual-scope-rebind-parameter", @@ -4377,7 +5273,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Rebinding a parameter does not change the caller's name\ndef changer(n1):\n n1 = n1 + 1\n return n1\n\na = 1\na = changer(a)\nprint(a)\nThe function works with its local parameter; the caller changes only because the returned value is assigned back to `a`.\n2", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-scope:w3-scope-core", + "snippet_label": "Global vs Local Names and Scope Errors" }, { "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", @@ -4389,7 +5287,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope" }, { "item_id": "exam-trial-final-exam-py22-2-w3-scope", @@ -4401,7 +5301,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?\na\nb\nc\nd\nb\nThe global variable 'a' is accessible inside the inner function without error. The code evaluates to inner(5) * 3 = (1 + 5 + 4) * 3 = 30.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "snippet_label": "Scope" }, { "item_id": "exam-Resit 22/23-2-w3-scope", @@ -4413,7 +5315,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope" }, { "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", @@ -4425,7 +5329,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope" }, { "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", @@ -4437,7 +5343,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The code will throw an UnboundLocalError or NameError when evaluating var_1 in 'var_2 = var_1 - var'.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope" }, { "item_id": "exam-extra_practice-2-w3-scope", @@ -4449,7 +5357,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modified to 3, print 3, then print val2=3. Output: 3,3. Option c: func3 creates local val3=3, prints 3. Global val3=2 unchanged, prints 2. Output: 3,2. Matches! Option d: innerfunc() called outside func4 scope — NameError. Correct: c.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "snippet_label": "Scope" }, { "item_id": "exam-midterm_2023-3-w3-scope", @@ -4461,7 +5371,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which other program will give the same output as the following code snippet?", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2023-3-w3-scope", + "snippet_label": "Scope" }, { "item_id": "exam-midterm_2024-5-w3-scope", @@ -4473,7 +5385,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which other program will produce the same output as the following code snippet?", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2024-5-w3-scope", + "snippet_label": "Scope" }, { "item_id": "ks-2a6510492d", @@ -4485,7 +5399,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local at call time, BEFORE executing the body — so if you assign to a name ANYWHERE in a function, that name is local throughout the function (even before the assignment line). Use 'global' keyword to override (but avoid it).\nLocal name not accessible outside\ndef adder(n1, n2):\n return n1 + n2\nadder(1, 2)\nprint(n1) # NameError: name 'n1' is not defined\nUnboundLocalError trap — local shadows global even before assignment\ndef main(a):\n b = b # ERROR: Python sees b assigned in function -> local\n return a # but local b has no value yet\nb = 1\nprint(main(1)) # UnboundLocalError\nglobal keyword\ndef changer():\n global n1\n n1 = n1 + 1\nn1 = 1\nchanger()\nprint(n1) # 2\nBetter pattern: avoid global\ndef changer(n1):\n n1 = n1 + 1\n return n1\na = 1\na = changer(a)\nprint(a) # 2\nMutable parameter is the SAME object\ndef adder(l2):\n result = 0\n while l2:\n result += l2.pop()\n return result\nl1 = [1, 2, 3, 4, 5]\ntotal = adder(l1)\nprint(f'The sum of {l1} = {total}') # The sum of [] = 15 !!!\n# l1 is empty because l2 and l1 refer to the SAME list object\nFix: copy mutable arg at start of function\ndef adder(l2):\n l2 = l2[:] # make a copy\n result = 0\n while l2:\n result += l2.pop()\n return result", - "week": 3 + "week": 3, + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope" }, { "item_id": "aiq-1", @@ -4497,7 +5413,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Mutable default argument\nCheck whether the method mutates the list in place and what the list looks like after each call.\nMutable default argument", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-1", + "snippet_label": "Arguments" }, { "item_id": "aiq-2", @@ -4509,7 +5427,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Mutable arguments\nMutating a passed list changes the caller's object; rebinding the parameter does not.\nMutable arguments", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-2", + "snippet_label": "Arguments" }, { "item_id": "aiq-3", @@ -4521,7 +5441,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-3", + "snippet_label": "Arguments" }, { "item_id": "aiq-4", @@ -4533,7 +5455,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we call the function as:\nprint_info('John', 30, city = 'New York', job = 'software engineer')\nthen it should return the dictionary:\n{'name' = 'John', 'age' = 30, 'city' = 'New York', 'job' = 'software engineer'}\nWhich of the following code snippets will do what you want?", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-4", + "snippet_label": "Arguments" }, { "item_id": "aiq-5", @@ -4545,7 +5469,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-value pairs:\namount: the number of the integers from the input list\nsmallest: the smallest integer from the input list\nlargest: the largest integer from the input list\ntotal: the sum of all integers from the input list\nWhich of the following functions will achieve what you need?", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-5", + "snippet_label": "Arguments" }, { "item_id": "aiq-6", @@ -4557,7 +5483,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-6", + "snippet_label": "Arguments" }, { "item_id": "aiq-7", @@ -4569,7 +5497,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Mutable parameter sharing\nWhen mutable object passed as argument, parameter and argument point to SAME object — mutations inside function affect original", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-7", + "snippet_label": "Arguments" }, { "item_id": "kp-1", @@ -4581,7 +5511,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Prefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "kp-1-d1", @@ -4593,7 +5525,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "*args usage\ndef adder(*args):\n result = 0\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15", - "week": 3 + "week": 3, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Arguments" }, { "item_id": "kp-1-d2", @@ -4605,7 +5539,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Mix defined and *args\ndef adder(n1, n2, *args):\n result = n1 + n2\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15", - "week": 3 + "week": 3, + "snippet_id": "item:kp-1-d2", + "snippet_label": "Arguments" }, { "item_id": "kp-2", @@ -4617,7 +5553,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Arguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "kp-2-d1", @@ -4629,7 +5567,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Keyword arguments\ndef calc(first, second, third, fourth, fifth, sixth):\n return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth\nprint(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63", - "week": 3 + "week": 3, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Arguments" }, { "item_id": "kp-2-d2", @@ -4641,7 +5581,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "**kwargs\ndef calc(**kwargs):\n return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third']\nprint(calc(third=4, second=2, first=3))", - "week": 3 + "week": 3, + "snippet_id": "item:kp-2-d2", + "snippet_label": "Arguments" }, { "item_id": "kp-3", @@ -4653,7 +5595,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Default values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "kp-3-d1", @@ -4665,7 +5609,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Default value\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3)) # 6 (uses default second=2)\nprint(multiplier(3, 3)) # 9\nprint(multiplier(2, second=3)) # 6", - "week": 3 + "week": 3, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Arguments" }, { "item_id": "kp-3-d2", @@ -4677,7 +5623,37 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Mutable default BUG\ndef main(addition, l1=[]):\n l1.append(addition)\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [2, 3] ← BUG: l1 persists!", - "week": 3 + "week": 3, + "snippet_id": "item:kp-3-d2", + "snippet_label": "Arguments" + }, + { + "item_id": "kp-manual-args-kwargs-return", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "A flexible header can mix fixed parameters, defaults, `*args`, and `**kwargs`, and a `return a, b` statement sends one tuple back to the caller that can be unpacked later.", + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" + }, + { + "item_id": "kp-manual-args-kwargs-return-d1", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Flexible signature reference\nPiece | Meaning\nfirst, second=0 | fixed parameters, one with a default\n*args | extra positional arguments as a tuple\n**kwargs | extra keyword arguments as a dict\nreturn a, b | returns one tuple that can be unpacked", + "week": 3, + "snippet_id": "item:kp-manual-args-kwargs-return-d1", + "snippet_label": "Arguments" }, { "item_id": "ai-example-1", @@ -4689,7 +5665,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "*args usage\ndef adder(*args):\n result = 0\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15\nPrefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "ai-example-2", @@ -4701,7 +5679,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Mix defined and *args\ndef adder(n1, n2, *args):\n result = n1 + n2\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15\nPrefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "ai-example-3", @@ -4713,7 +5693,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Keyword arguments\ndef calc(first, second, third, fourth, fifth, sixth):\n return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth\nprint(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63\nArguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "ai-example-4", @@ -4724,8 +5706,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Function return value and trace\ndef calc(**kwargs):\n return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third']\nprint(calc(third=4, second=2, first=3))\nArguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.", - "week": 3 + "search_text": "`**kwargs` behaves like a dict\ndef calc(**kwargs):\n return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third']\nprint(calc(third=4, second=2, first=3))\nArguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.", + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "ai-example-5", @@ -4737,7 +5721,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Default value\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3)) # 6 (uses default second=2)\nprint(multiplier(3, 3)) # 9\nprint(multiplier(2, second=3)) # 6\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "ai-example-6", @@ -4749,7 +5735,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Mutable default BUG\ndef main(addition, l1=[]):\n l1.append(addition)\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [2, 3] ← BUG: l1 persists!\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "ai-example-7", @@ -4760,8 +5748,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Function return value and trace\ndef adder(n1, n2):\n return n1 + n2\nprint(adder(1, 2))\nTrace the returned value, not just what gets printed while the function runs.", - "week": 3 + "search_text": "Return value with required positional args\ndef adder(n1, n2):\n return n1 + n2\nprint(adder(1, 2))\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "ai-example-8", @@ -4772,8 +5762,24 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Function return value and trace\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3))\nTrace the returned value, not just what gets printed while the function runs.", - "week": 3 + "search_text": "Default argument still returns one value\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3))\nTrace the returned value, not just what gets printed while the function runs.", + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" + }, + { + "item_id": "manual-args-kwargs-return", + "card_id": "w3-arguments", + "topic": "Arguments", + "subtopic_id": "w3-arguments-core", + "subtopic_title": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Flexible header plus tuple return\ndef collect(first, *args, scale=1, **kwargs):\n return first * scale, args, kwargs\n\nresult, extras, options = collect(2, 3, 4, scale=10, unit='cm')\nprint(result)\nprint(extras)\nprint(options['unit'])\nThis combines the most important exam mechanics in one place: fixed parameters, `*args`, `**kwargs`, and unpacking a tuple returned by the function.\n20\n(3, 4)\ncm", + "week": 3, + "snippet_id": "subtopic:w3-arguments:w3-arguments-core", + "snippet_label": "Positional, Keyword, Default, *args, **kwargs, and Mutable Argument Traps" }, { "item_id": "exam-intro_python_sample_final_24_25-23-w3-arguments", @@ -4785,7 +5791,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which of the following function calls would return the number 30 as a result?\nA\nB\nC\nD\nC\nThe first call sums (6+7+8+9)=30. The second call sums (1+4+9+16)=30.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-intro_python_sample_final_24_25-23-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "exam-Resit 22/23-4-w3-arguments", @@ -4797,7 +5805,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run for `i` from 1 to 10 inclusive, resulting in a list of 10 formatted multiplication strings.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", @@ -4809,7 +5819,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\n\nWhich of the following functions will return the intended value?\na\nb\nc\nd\nb\nOption B correctly iterates over the values of the kwargs dictionary and adds each price to the total. Option A would cause a TypeError because it tries to add a string key ('item') to an integer.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "exam-Resit 22/23-6-w3-arguments", @@ -4821,7 +5833,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.47\nWhich of the following functions will return the intended value?\na\nb\nc\nd\nb\nOption B correctly iterates through the values of the `kwargs` dictionary using `kwargs.values()` and sums them. Option A tries to add the keys (`item`), which are strings. Option C tries to unpack keys into two variables, which will fail or iterate through string characters incorrectly.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "exam-midterm_2023-9-w3-arguments", @@ -4833,7 +5847,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB 40\n45\nThe code will result in TypeError because there is a missing argument.\nC 25\n35\n35\nD All three lines of code will result in TypeError because there is a missing argument.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "exam-midterm_2023-10-w3-arguments", @@ -4845,7 +5861,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "exam-midterm_2024-13-w3-arguments", @@ -4857,7 +5875,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have to write a function called summarize which take a list of integers as an argument.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2024-13-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "exam-midterm_2024-14-w3-arguments", @@ -4869,7 +5889,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, factor=3)\nmultiply(3, 4)\nmultiply()\nA def multiply(*args, factor=2):\ntotal = args[0]\nfor num in args:\ntotal *= num\nreturn total * factor\nB def multiply(*args, factor=2):\nif not args:\nreturn 0\ntotal = args[0]\nfor num in args[1:]:\ntotal *= num\nreturn total * factor\nC Both functions will return the same values.\nD Neither functions will return the same values.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments" }, { "item_id": "ks-40fee04740", @@ -4881,7 +5903,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "*args — undefined number of positional arguments\nPrefixing a parameter with * makes Python collect all extra positional arguments into a tuple named args. Can mix with defined parameters: def f(n1, n2, *args) — Python fills n1,n2 first then collects remainder into args.\n*args usage\ndef adder(*args):\n result = 0\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15\nMix defined and *args\ndef adder(n1, n2, *args):\n result = n1 + n2\n for number in args:\n result += number\n return result\nprint(adder(1, 2, 3, 4, 5)) # 15", - "week": 3 + "week": 3, + "snippet_id": "item:ks-40fee04740", + "snippet_label": "Arguments" }, { "item_id": "ks-f5d65c7e89", @@ -4893,7 +5917,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Keyword arguments and **kwargs\nArguments can be passed by name (keyword). **kwargs collects undefined keyword arguments into a dict. Order in function definition: positional, *args, keyword-with-defaults, **kwargs.\nKeyword arguments\ndef calc(first, second, third, fourth, fifth, sixth):\n return first + 2*second + 3*third + 4*fourth + 5*fifth + 6*sixth\nprint(calc(fifth=2, third=4, fourth=1, sixth=5, second=2, first=3)) # 63\n**kwargs\ndef calc(**kwargs):\n return kwargs['first'] + 2*kwargs['second'] + 3*kwargs['third']\nprint(calc(third=4, second=2, first=3))\nMixed: positional + *args + **kwargs\ndef calc(first, second, *args, **kwargs):\n return first + second*2 + args[0]*3 + args[1]*4 + 5*kwargs['fifth'] + 6*kwargs['sixth']\nprint(calc(3, 2, 4, 1, sixth=5, fifth=2)) # 63", - "week": 3 + "week": 3, + "snippet_id": "item:ks-f5d65c7e89", + "snippet_label": "Arguments" }, { "item_id": "ks-d26b85265c", @@ -4905,7 +5931,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Default arguments\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.\nDefault value\ndef multiplier(first, second=2):\n return first * second\nprint(multiplier(3)) # 6 (uses default second=2)\nprint(multiplier(3, 3)) # 9\nprint(multiplier(2, second=3)) # 6\nMutable default BUG\ndef main(addition, l1=[]):\n l1.append(addition)\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [2, 3] ← BUG: l1 persists!\nMutable default FIX — use None\ndef main(addition, l1=None):\n if l1 is None:\n l1 = []\n l1 += [addition]\n return l1\nprint(main(2)) # [2]\nprint(main(3)) # [3] ← correct", - "week": 3 + "week": 3, + "snippet_id": "item:ks-d26b85265c", + "snippet_label": "Arguments" }, { "item_id": "aiq-1", @@ -4917,7 +5945,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • trial_midterm • Q17\nA def squared_function(x):\nreturn x**2\nprint(squared_function([1, 2, 3]))\nB print(list(map(lambda x: x**2, [1, 2, 3])))\nC def squared_function(x):\nreturn x**2\nprint(list(map(squared_function, [1, 2, 3])))\nD squared_numbers = lambda x: x**2\nprint([squared_numbers(1), squared_numbers(2), squared_numbers(3)])", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-1", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "aiq-2", @@ -4929,7 +5959,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\nthen it should return the list:\n[-10, -9, 7, 5, 4, -3, 2]\nWhich of the following functions will give you the correct output?", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-2", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "aiq-3", @@ -4941,7 +5973,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such as:\nmy_list = [0, 1, 2, 3, 4]\nyou want to print:\n[0, 0]\n[1, 1]", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-3", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "aiq-5", @@ -4953,7 +5987,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: ", - "week": 3 + "week": 3, + "snippet_id": "item:aiq-5", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "kp-1", @@ -4965,7 +6001,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Functions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "kp-1-d1", @@ -4977,7 +6015,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Function factory\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\nadd4 = function_factory(4)\nadd5 = function_factory(5)\nprint(add4(3)) # 7\nprint(add5(3)) # 8", - "week": 3 + "week": 3, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "kp-1-d2", @@ -4989,7 +6029,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nTool | Returns | Best for\nmap(f, seq) | lazy transformed iterable | same-length transform\nfilter(f, seq) | lazy filtered iterable | keep matching items\nsorted(seq, key=...) | new sorted list | comparison key\nlambda x: ... | anonymous function | small inline transform", - "week": 3 + "week": 3, + "snippet_id": "item:kp-1-d2", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "kp-2", @@ -5001,7 +6043,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Anonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "kp-2-d1", @@ -5013,7 +6057,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Lambda basics\nadd_two = lambda x, y: x + y\nprint(add_two(1, 2)) # 3\n# Equivalent to:\ndef add_two(x, y):\n return x + y", - "week": 3 + "week": 3, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "kp-2-d2", @@ -5025,7 +6071,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "map() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12]\n# Need list() to convert map object to list", - "week": 3 + "week": 3, + "snippet_id": "item:kp-2-d2", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "kp-3", @@ -5036,8 +6084,24 @@ "item_type": "key_point", "bucket": "keyPoints", "selection_kind": "direct", - "search_text": "def function_factory(increment): def adder(n1): return n1 + increment return adder add4 = function_factory(4) add5 = function_factory (5) print(add4(3)) print(add5(3))", - "week": 3 + "search_text": "`lambda x: expr` names one element at a time, and `map(f, seq)` returns a lazy iterable. Wrap it in `list(...)` when you need to inspect or print the mapped results.", + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" + }, + { + "item_id": "kp-3-d1", + "card_id": "w3-higher-order-patterns", + "topic": "Higher-Order Patterns", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Compact lambda / map reference\nPattern | Meaning\nlambda x: x * 2 | inline function for one value\nmap(f, seq) | apply `f` to each element lazily\nlist(map(f, seq)) | materialize the mapped results for display", + "week": 3, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "ai-example-1", @@ -5049,7 +6113,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Function factory\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\nadd4 = function_factory(4)\nadd5 = function_factory(5)\nprint(add4(3)) # 7\nprint(add5(3)) # 8\nFunctions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "ai-example-2", @@ -5061,7 +6127,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Lambda basics\nadd_two = lambda x, y: x + y\nprint(add_two(1, 2)) # 3\n# Equivalent to:\ndef add_two(x, y):\n return x + y\nAnonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "ai-example-3", @@ -5073,7 +6141,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "map() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12]\n# Need list() to convert map object to list\nAnonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "ai-example-4", @@ -5084,8 +6154,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Elementwise transformation with `map`/`lambda`\nprint((lambda x, y: 2*x*y)(4, 3))\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.", - "week": 3 + "search_text": "`map` can combine multiple iterables\nleft = [1, 2, 3]\nright = [10, 20, 30]\nprint(list(map(lambda x, y: x + y, left, right)))\nA lambda can take multiple parameters, and `map(...)` then feeds one element from each iterable into that lambda on every step.", + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "ai-example-5", @@ -5097,7 +6169,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "sorted_key\nl1 = ['a', 'B', 'c']\nprint(sorted(l1))", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "ai-example-6", @@ -5109,7 +6183,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "sorted_key\nl1 = ['ad', 'dc', 'ce']\nprint(sorted(l1))", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "ai-example-7", @@ -5121,7 +6197,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "sorted_builtins\nl1 = ['aaa', 'bb', 'c']\nprint(sorted(l1))", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "ai-example-8", @@ -5133,7 +6211,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "sorted_builtins\nl1 = ['aaa', 'bb', 'c']\nprint(sorted(l1, key=len))", - "week": 3 + "week": 3, + "snippet_id": "subtopic:w3-higher-order-patterns:w3-higher-order-patterns-core", + "snippet_label": "Nested Functions, Factories, lambda, map, filter, reduce, and sorted(key=...)" }, { "item_id": "exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", @@ -5145,7 +6225,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "What would be printed by the following code snippet: print(list_1[0](1, 2) ** list_1[1](1, 2))\nA\nB\nC\nD\nD\nlist_1[0](1, 2) is 1 + 2 = 3. list_1[1](1, 2) is 1 * 2 = 2. 3 ** 2 = 9.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-intro_python_sample_final_24_25-16-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "exam-midterm_2023-11-w3-higher-order-patterns", @@ -5157,7 +6239,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You need to write a function called sort_list that accepts a list of integers.\nThe function should return a new list, in which the elements are sorted from highest to lowest based on their absolute values.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2023-11-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", @@ -5169,7 +6253,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such as:\nmy_list = [0, 1, 2, 3, 4]\nyou want to print:\n[0, 0]\n[1, 1]\n[4, 8]\n[9, 27]\n[16, 64]\nWhich of the following blocks of codes works as intended?\nA funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x(i), funcs)\nprint(list(results))\nB funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x[i], funcs)\nprint(list(results))\nC funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x(i), funcs)\nprint(results)\nD funcs = [square, cube]\nfor i in my_list:\nresults = map(lambda x: x[i], funcs)\nprint(results)", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "exam-trial_midterm-17-w3-higher-order-patterns", @@ -5181,7 +6267,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nWhich block of code prints something different than the other blocks print?", - "week": 3 + "week": 3, + "snippet_id": "item:exam-trial_midterm-17-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "exam-midterm_2024-19-w3-higher-order-patterns", @@ -5193,7 +6281,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nWhich block of code prints something different than the other blocks print?", - "week": 3 + "week": 3, + "snippet_id": "item:exam-midterm_2024-19-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "ks-f069ee6a0b", @@ -5205,7 +6295,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Nested functions and function factories\nFunctions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).\nFunction factory\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\nadd4 = function_factory(4)\nadd5 = function_factory(5)\nprint(add4(3)) # 7\nprint(add5(3)) # 8", - "week": 3 + "week": 3, + "snippet_id": "item:ks-f069ee6a0b", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "ks-58858d6d96", @@ -5217,7 +6309,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Lambda functions\nAnonymous one-line functions. Syntax: lambda params: expression. Equivalent to a regular def but more concise. Most useful with map, filter, reduce, sorted, max.\nLambda basics\nadd_two = lambda x, y: x + y\nprint(add_two(1, 2)) # 3\n# Equivalent to:\ndef add_two(x, y):\n return x + y\nmap() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(map(lambda x: x * 2, l1))) # [2, 4, 6, 8, 10, 12]\n# Need list() to convert map object to list\nfilter() with lambda\nl1 = [1, 2, 3, 4, 5, 6]\nprint(list(filter(lambda x: not x % 2, l1))) # [2, 4, 6] (even numbers)\nreduce() with lambda\nfrom functools import reduce\nl1 = [1, 2, 3, 4, 5, 6]\nprint(reduce(lambda x, y: x*y, l1)) # 720 (product)\n# reduce with initial value:\nl1 = ['aaa', 'baab', 'c']\nprint(reduce(lambda x, y: x + y.count('a'), l1, 0)) # 5\nsorted() with key lambda\nl1 = ['aaa', 'c', 'baab']\nprint(sorted(l1)) # ['aaa', 'baab', 'c']\nprint(sorted(l1, key=lambda x: x.count('a'))) # ['c', 'baab', 'aaa']\nprint(sorted(l1, key=len)) # ['c', 'aaa', 'baab']\n\nd = {'a': 2, 'b': 1}\nprint(max(d.items())) # ('b', 1) ← compares tuples\nprint(max(d.items(), key=lambda x: x[1])) # ('a', 2) ← by value", - "week": 3 + "week": 3, + "snippet_id": "item:ks-58858d6d96", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "ks-994a4083e3", @@ -5229,7 +6323,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "function_factories\ndef function_factory(increment):\n def adder(n1):\n return n1 + increment\n return adder\n\nadd4 = function_factory(4)\nadd5 = function_factory (5)\n\nprint(add4(3))\nprint(add5(3))", - "week": 3 + "week": 3, + "snippet_id": "item:ks-994a4083e3", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "exam-extra_practice-10-w3-higher-order-patterns", @@ -5241,7 +6337,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the following code snippets achieve what you want?\na\nb\nc\nd\nb\nOption a produces both (5,6) and (6,5) — it doesn't ensure uniqueness. Option b iterates up to target//2, so each pair is only considered once. For target=11, range(0,6): checks 0,1,2,3,4,5. Finds: 2+9,3+8,4+7,5+6 — unique pairs. Option b works as intended. Option a doesn't meet the uniqueness requirement. Correct: b.", - "week": 3 + "week": 3, + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "cs-curated-hw-hof-nested-helper-hhi", @@ -5253,7 +6351,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "A nested helper can hide repeated domain math inside one outer function\ndef main(sales_before_entry):\n def calculate_hhi(sales_volumes):\n total_sales = sum(sales_volumes)\n return sum(round(100 * volume / total_sales) ** 2 for volume in sales_volumes)\n\n before = calculate_hhi(sales_before_entry)\n after = calculate_hhi(sales_before_entry + [40])\n return before - after\n\nprint(main([47, 21, 27, 29, 11, 6, 18]))\n224", - "week": 3 + "week": 3, + "snippet_id": "item:cs-curated-hw-hof-nested-helper-hhi", + "snippet_label": "Higher-Order Patterns" }, { "item_id": "aiq-1", @@ -5265,7 +6365,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Given s1 = 'abcd', which code fragment correctly updates s1 to 'Abcd'?\nStrings are immutable. s1.capitalize() returns a new string, so you must assign that result back to the name s1.\nString Methods", - "week": 4 + "week": 4, + "snippet_id": "item:aiq-1", + "snippet_label": "String Fundamentals" }, { "item_id": "manual-string-immutability", @@ -5277,7 +6379,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Why does `s[0] = 'A'` fail?\nStrings are immutable, so you must build a new string such as `s = 'A' + s[1:]` instead of assigning by index.\ns = 'abcd'\ns = 'A' + s[1:]", - "week": 4 + "week": 4, + "snippet_id": "item:manual-string-immutability", + "snippet_label": "String Fundamentals" }, { "item_id": "manual-string-escapes", @@ -5289,7 +6393,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do you include quotes or a newline inside a string literal?\nPick the other quote style or escape the inner quote; use `\\n` for a newline.\nprint(\"it's\")\nprint('He said \"hi\"')\nprint(\"Line 1\\nLine 2\")", - "week": 4 + "week": 4, + "snippet_id": "item:manual-string-escapes", + "snippet_label": "String Fundamentals" }, { "item_id": "kp-1", @@ -5301,7 +6407,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Strings are immutable: methods like `.upper()` and `.replace()` return a new string, so assign the result back if you want the change to stick.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "kp-1-d1", @@ -5313,7 +6421,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Attempting to change a string\ns1 = 'abcd'\ns1.capitalize() # Returns 'Abcd'\nprint(s1) # Still prints 'abcd'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-1-d1", + "snippet_label": "String Fundamentals" }, { "item_id": "kp-1-d2", @@ -5325,7 +6435,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nForm | What it means | Exam use\n'...'/\"...\" | basic literals | choose quote style\n\\n / \\t | newline / tab | predict printed output\nr'...' | raw string | slashes stay literal\ns[i:j:k] | string slicing | same rules as sequences", - "week": 4 + "week": 4, + "snippet_id": "item:kp-1-d2", + "snippet_label": "String Fundamentals" }, { "item_id": "kp-2", @@ -5337,7 +6449,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Escape sequences: `\\n` newline, `\\t` tab, and `\\'` or `\\\"` for literal quotes.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "kp-2-d1", @@ -5349,7 +6463,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Newlines and tabs\nprint('Line 1\\nLine 2\\tTabbed')\nprint(\"It\\'s a string\")", - "week": 4 + "week": 4, + "snippet_id": "item:kp-2-d1", + "snippet_label": "String Fundamentals" }, { "item_id": "kp-3", @@ -5361,7 +6477,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Strings are immutable: `s[0] = 'A'` fails, so rebuild or rebind, for example `s = 'A' + s[1:]`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "ai-example-1", @@ -5373,7 +6491,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Methods return new strings\ns1 = 'abcd'\ns1.capitalize() # Returns 'Abcd'\nprint(s1) # Still prints 'abcd'\nStrings are immutable: methods like `.upper()` and `.replace()` return a new string, so assign the result back if you want the change to stick.\nabcd", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "ai-example-2", @@ -5385,7 +6505,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Newlines and tabs\nprint('Line 1\\nLine 2\\tTabbed')\nprint(\"It\\'s a string\")\nEscape sequences: `\\n` newline, `\\t` tab, and `\\'` or `\\\"` for literal quotes.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "ai-example-4", @@ -5397,7 +6519,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Filter uppercase letters with a helper function\ndef my_isupper(s1):\n for el in s1:\n if el not in \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\":\n return False\n return True \n\nx = \"Harry Potter and the Philosopher's Stone\"\ny = ''\nfor i in x:\n if my_isupper(i):\n y += i\nprint(y)\nTrace the loop character by character and keep only the uppercase letters that satisfy the test.\nHPPS", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "ai-example-8", @@ -5409,7 +6533,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`len(s)` counts characters\na = 'adbc'\nprint(len(a))\nCount every character in the string, including letters, spaces, and punctuation if they are present.\n4", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "manual-string-literals-example", @@ -5421,7 +6547,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Quotes and newline escapes\nprint(\"it's\")\nprint('He said \"hi\"')\nprint(\"Line 1\\nLine 2\")\nUse matching quotes or escape the inner quote; `\\n` inserts a newline.\nit's\nHe said \"hi\"\nLine 1\nLine 2", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-fundamentals:w4-string-fundamentals-core", + "snippet_label": "Quotes, Escape Characters, and Immutability" }, { "item_id": "ks-b734a22f46", @@ -5433,7 +6561,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "String Immutability\nStrings in Python are immutable, meaning they cannot be changed in place. Methods like upper() or replace() return a new string object rather than modifying the original.\nAttempting to change a string\ns1 = 'abcd'\ns1.capitalize() # Returns 'Abcd'\nprint(s1) # Still prints 'abcd'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-b734a22f46", + "snippet_label": "String Fundamentals" }, { "item_id": "ks-309158a68c", @@ -5445,7 +6575,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Escape Characters\nSpecial characters like newlines (\\n), tabs (\\t), or literal quotes can be included using the backslash (\\).\nNewlines and tabs\nprint('Line 1\\nLine 2\\tTabbed')\nprint(\"It\\'s a string\")", - "week": 4 + "week": 4, + "snippet_id": "item:ks-309158a68c", + "snippet_label": "String Fundamentals" }, { "item_id": "cs-e7bc165499", @@ -5457,7 +6589,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "def main(a, b):\ndef main(a, b):\n return f'''The first number is: {a:04d}\nThe second number is: {b:04d}\nThe product is: {a * b:04d}'''\nprint(main(7,13))\nThe first number is: 0007\nThe second number is: 0013\nThe product is: 0091", - "week": 4 + "week": 4, + "snippet_id": "item:cs-e7bc165499", + "snippet_label": "String Fundamentals" }, { "item_id": "cs-14245b8c1f", @@ -5469,7 +6603,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "def my_isupper(s1):\ndef my_isupper(s1):\n for el in s1:\n if el not in \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\":\n return False\n return True \n\nx = \"Harry Potter and the Philosopher's Stone\"\ny = ''\nfor i in x:\n if my_isupper(i):\n y += i\nprint(y)\nHPPS", - "week": 4 + "week": 4, + "snippet_id": "item:cs-14245b8c1f", + "snippet_label": "String Fundamentals" }, { "item_id": "aiq-2", @@ -5481,7 +6617,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing", - "week": 4 + "week": 4, + "snippet_id": "item:aiq-2", + "snippet_label": "String Operations and Methods" }, { "item_id": "aiq-5", @@ -5493,7 +6631,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy", - "week": 4 + "week": 4, + "snippet_id": "item:aiq-5", + "snippet_label": "String Operations and Methods" }, { "item_id": "aiq-6", @@ -5505,7 +6645,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "range() and slicing both exclusive at stop\nrange(1,10,3)→[1,4,7] not including 10; l[2:7] goes up to but not including index 7", - "week": 4 + "week": 4, + "snippet_id": "item:aiq-6", + "snippet_label": "String Operations and Methods" }, { "item_id": "manual-find-vs-index", @@ -5517,7 +6659,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What is the difference between `s.find(x)` and `s.index(x)` when `x` is missing?\n`find` returns `-1`; `index` raises `ValueError`.\ns = 'banana'\nprint(s.find('x'))\nprint(s.index('x')) # ValueError", - "week": 4 + "week": 4, + "snippet_id": "item:manual-find-vs-index", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-1", @@ -5529,7 +6673,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Both find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-1-d1", @@ -5541,7 +6687,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Behavior when substring is missing\ns = 'abc'\nprint(s.find('z')) # -1\n# print(s.index('z')) # Raises ValueError", - "week": 4 + "week": 4, + "snippet_id": "item:kp-1-d1", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-1-d2", @@ -5553,7 +6701,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nMethod | Returns | Trap\ns.find(x) | index or -1 | never raises\ns.index(x) | index | raises if missing\ns.replace(a, b) | new string | strings are immutable\nsep.join(seq) | new joined string | separator is the caller", - "week": 4 + "week": 4, + "snippet_id": "item:kp-1-d2", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-2", @@ -5565,7 +6715,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Slicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-2-d1", @@ -5577,7 +6729,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Slicing examples\ns = '01234567'\nprint(s[::4]) # '04'\nprint(s[::-2]) # '7531'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-2-d1", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-3", @@ -5589,7 +6743,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "The join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-3-d1", @@ -5601,7 +6757,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Joining a list into a string\nwords = ['a', 'b', 'c']\nprint('-'.join(words)) # 'a-b-c'\nprint(''.join(words)) # 'abc'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-3-d1", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-4", @@ -5613,7 +6771,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Replaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-4-d1", @@ -5625,7 +6785,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Limiting replacements\ns = 'aaaa'\nprint(s.replace('a', 'b', 2)) # 'bbaa'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-4-d1", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-5", @@ -5637,7 +6799,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "The 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-5-d1", @@ -5649,7 +6813,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Importing string constants\nimport string\nprint(string.ascii_lowercase) # 'abcdef...'\nprint(string.digits) # '0123456789'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-5-d1", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-6", @@ -5661,7 +6827,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "strip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-6-d1", @@ -5673,7 +6841,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Stripping whitespace and characters\ns = ' abc '\nprint(s.strip()) # 'abc'\ns2 = 'eeabcdee'\nprint(s2.strip('e')) # 'abcd'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-6-d1", + "snippet_label": "String Operations and Methods" }, { "item_id": "kp-7", @@ -5685,7 +6855,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Pattern to remember: `find` returns `-1`; `index` raises `ValueError` if the substring is missing.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-manual-string-method-results", @@ -5697,7 +6869,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "String methods like `replace`, `capitalize`, `split`, and `join` return new values; the original string stays unchanged unless you assign the result.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "kp-manual-string-method-results-d1", @@ -5709,7 +6883,65 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "replace() returns a new string\nnumber = '020-525-1400'\ncleaned = number.replace('-', '')\nprint(number) # '020-525-1400'\nprint(cleaned) # '0205251400'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-manual-string-method-results-d1", + "snippet_label": "String Operations and Methods" + }, + { + "item_id": "kp-8", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Indexing and slicing are exam staples: `s[i]` gets one character, `s[-1]` starts from the end, and slices use an exclusive stop with optional step values such as `s[1:5]`, `s[::2]`, and `s[::-1]`.", + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" + }, + { + "item_id": "kp-8-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Indexing and slicing quick rules\nPattern | Meaning | Trap\ns[0], s[-1] | first / last character | single-index access can raise IndexError\ns[a:b] | start inclusive, stop exclusive | safe even if b is past the end\ns[::2] | every second character | step changes which positions survive\ns[::-1] | reversed string | negative step walks from right to left", + "week": 4, + "snippet_id": "item:kp-8-d1", + "snippet_label": "String Operations and Methods" + }, + { + "item_id": "kp-9", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Boolean string predicates answer slightly different questions: `.islower()` and `.isupper()` need at least one cased character, `.isdigit()` checks digits only, and spaces or punctuation usually make the result `False`.", + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" + }, + { + "item_id": "kp-9-d1", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Predicate truth table\nInput | Check | Result\n'abc'.islower() | all cased chars lowercase | True\n'Abc'.islower() | contains uppercase | False\n'123'.isdigit() | all chars are digits | True\n'abc!'.islower() | punctuation ignored, cased chars still lowercase | True\n'abc 1'.isdigit() | letters/spaces are not digits | False", + "week": 4, + "snippet_id": "item:kp-9-d1", + "snippet_label": "String Operations and Methods" }, { "item_id": "ai-example-1", @@ -5721,7 +6953,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Behavior when substring is missing\ns = 'abc'\nprint(s.find('z')) # -1\n# print(s.index('z')) # Raises ValueError\nBoth find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "ai-example-2", @@ -5733,7 +6967,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Slicing examples\ns = '01234567'\nprint(s[::4]) # '04'\nprint(s[::-2]) # '7531'\nSlicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "ai-example-3", @@ -5745,7 +6981,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Joining a list into a string\nwords = ['a', 'b', 'c']\nprint('-'.join(words)) # 'a-b-c'\nprint(''.join(words)) # 'abc'\nThe join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "ai-example-4", @@ -5757,7 +6995,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Limiting replacements\ns = 'aaaa'\nprint(s.replace('a', 'b', 2)) # 'bbaa'\nReplaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "ai-example-5", @@ -5769,7 +7009,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Importing string constants\nimport string\nprint(string.ascii_lowercase) # 'abcdef...'\nprint(string.digits) # '0123456789'\nThe 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "ai-example-6", @@ -5781,7 +7023,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Stripping whitespace and characters\ns = ' abc '\nprint(s.strip()) # 'abc'\ns2 = 'eeabcdee'\nprint(s2.strip('e')) # 'abcd'\nstrip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "ai-example-7", @@ -5793,7 +7037,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "s1 = 'abcdefghabcdefgh'\ns1 = 'abcdefghabcdefgh'\nprint(s1.find('i'))\nprint(s1[s1.find('i')])\nprint(s1.index('i'))", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "ai-example-8", @@ -5805,7 +7051,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "s1 = 'abcdefghabcdefgh'\ns1 = 'abcdefghabcdefgh'\nprint(s1.find('e'))\nprint(s1.index('e', 5))\nprint(s1.find('e', 5, 10))\nprint(s1.index('e', 5, 13))\nprint(s1.find('ef'))\nprint(s1.index('q'))", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "manual-string-format-method", @@ -5817,7 +7065,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Build strings with `.format(...)`\ntemplate = \"{} scored {} points\"\nprint(template.format(\"Ada\", 9))\nUse `.format(...)` on the template string, and remember it returns a new string instead of changing the original text in place.\nAda scored 9 points", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "manual-string-islower-method", @@ -5829,7 +7079,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Check lowercase letters with `.islower()`\nprint(\"amsterdam\".islower())\nprint(\"Amsterdam\".islower())\nprint(\"123\".islower())\n`.islower()` only returns `True` when the string contains at least one cased character and all cased characters are lowercase.\nTrue\nFalse\nFalse", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "manual-string-repetition", @@ -5841,7 +7093,37 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Repeat text with string multiplication\nprint(3 * \"ha\")\nprint(\"ab\" * 2)\nBoth `n * text` and `text * n` repeat the string `n` times, which is a common concise exam pattern.\nhahaha\nabab", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" + }, + { + "item_id": "manual-string-indexing-reference", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Indexing, negative indices, and slices\ns = 'python'\nprint(s[0], s[-1])\nprint(s[1:4])\nprint(s[::2])\nprint(s[::-1])\nThis compact reference covers the most repeated string-selection patterns: direct indexing, negative indexing, exclusive-stop slicing, step slicing, and reversal.\np n\nyth\npto\nnohtyp", + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" + }, + { + "item_id": "manual-string-output-construction", + "card_id": "w4-string-operations-and-methods", + "topic": "String Operations and Methods", + "subtopic_id": "w4-string-operations-and-methods-core", + "subtopic_title": "Slicing with Step, Search, replace, join, strip, and the string Module", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Join values into exam-style output text\nnames = ['Ada', 'Bob', 'Cleo']\nbody = ', '.join(names[:-1])\nprint(f'{body}, and {names[-1]}')\nprint('{:.2f}'.format(3.5))\nUse `join` for the repeated separator, then add the custom tail separately when the output must end with words like `, and ...`.\nAda, Bob, and Cleo\n3.50", + "week": 4, + "snippet_id": "subtopic:w4-string-operations-and-methods:w4-string-operations-and-methods-core", + "snippet_label": "Slicing with Step, Search, replace, join, strip, and the string Module" }, { "item_id": "exam-intro_python_sample_final_24_25-4-w2-conditions", @@ -5853,7 +7135,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which of the following code segments does NOT achieve the goal of returning a string with 10 digits by removing dashes?\nA\nB\nC\nD\nA\nStrings in Python are immutable. The .replace() method returns a new string but does not modify the original. Option A returns the original string with dashes because the result of .replace() was not assigned back to the variable.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-intro_python_sample_final_24_25-4-w2-conditions", + "snippet_label": "String Operations and Methods" }, { "item_id": "exam-intro_python_sample_final_24_25-22-w2-conditions", @@ -5865,7 +7149,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which script, using the count string method, would print the value 1 for x = 'Amsterdam'?\nA\nB\nC\nD\nB\nThe count() method is a string method, not a standalone function. It is called using the dot notation on a string object.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-intro_python_sample_final_24_25-22-w2-conditions", + "snippet_label": "String Operations and Methods" }, { "item_id": "ks-5198d93ec1", @@ -5877,7 +7163,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "String Searching: find vs index\nBoth find() and index() search for a substring. The key difference is that find() returns -1 if the substring is not found, while index() raises a ValueError.\nBehavior when substring is missing\ns = 'abc'\nprint(s.find('z')) # -1\n# print(s.index('z')) # Raises ValueError", - "week": 4 + "week": 4, + "snippet_id": "item:ks-5198d93ec1", + "snippet_label": "String Operations and Methods" }, { "item_id": "ks-f80f1bf556", @@ -5889,7 +7177,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "String Slicing with Step\nSlicing allows a third parameter 'step'. s[::2] takes every second character, while s[::-1] reverses the string.\nSlicing examples\ns = '01234567'\nprint(s[::4]) # '04'\nprint(s[::-2]) # '7531'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-f80f1bf556", + "snippet_label": "String Operations and Methods" }, { "item_id": "ks-cdb152720e", @@ -5901,7 +7191,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "The join Method\nThe join() method takes an iterable (like a list) and concatenates its elements using the string it is called on as a separator.\nJoining a list into a string\nwords = ['a', 'b', 'c']\nprint('-'.join(words)) # 'a-b-c'\nprint(''.join(words)) # 'abc'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-cdb152720e", + "snippet_label": "String Operations and Methods" }, { "item_id": "ks-45aead894c", @@ -5913,7 +7205,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "The replace Method\nReplaces occurrences of a substring. It accepts an optional 'count' argument to limit the number of replacements.\nLimiting replacements\ns = 'aaaa'\nprint(s.replace('a', 'b', 2)) # 'bbaa'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-45aead894c", + "snippet_label": "String Operations and Methods" }, { "item_id": "ks-bdea67862f", @@ -5925,7 +7219,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "The string Module\nThe 'string' module provides pre-defined constants like all lowercase letters, digits, and punctuation.\nImporting string constants\nimport string\nprint(string.ascii_lowercase) # 'abcdef...'\nprint(string.digits) # '0123456789'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-bdea67862f", + "snippet_label": "String Operations and Methods" }, { "item_id": "ks-e4dc502d3e", @@ -5937,7 +7233,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "String Stripping\nstrip() removes leading and trailing characters. lstrip() and rstrip() target the left and right sides respectively.\nStripping whitespace and characters\ns = ' abc '\nprint(s.strip()) # 'abc'\ns2 = 'eeabcdee'\nprint(s2.strip('e')) # 'abcd'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-e4dc502d3e", + "snippet_label": "String Operations and Methods" }, { "item_id": "aiq-1", @@ -5949,7 +7247,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do you include literal curly braces {} in an f-string?\nIn f-strings, curly braces are escaped by doubling them ({{ and }}).\nF-strings", - "week": 4 + "week": 4, + "snippet_id": "item:aiq-1", + "snippet_label": "String Formatting" }, { "item_id": "kp-1", @@ -5961,7 +7261,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "F-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "kp-1-d1", @@ -5973,7 +7275,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Simple f-string\nname = 'Jan'\nprint(f'{name} studies Python.') # 'Jan studies Python.'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-1-d1", + "snippet_label": "String Formatting" }, { "item_id": "kp-2", @@ -5985,7 +7289,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Using f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "kp-2-d1", @@ -5997,7 +7303,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Debug shortcut\nval = 10\nprint(f'{val=}') # 'val=10'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-2-d1", + "snippet_label": "String Formatting" }, { "item_id": "kp-3", @@ -6009,7 +7317,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "You can specify formatting after a colon, such as padding numbers with zeros.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "kp-3-d1", @@ -6021,7 +7331,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Zero-padding an integer\nnum = 7\nprint(f'{num:03d}') # '007'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-3-d1", + "snippet_label": "String Formatting" }, { "item_id": "kp-4", @@ -6033,7 +7345,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Official assessments also use `.format(...)` placeholders. The same width and zero-padding ideas still apply there, for example `'{:04d}'.format(n)`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "kp-4-d1", @@ -6045,7 +7359,37 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Padding with `.format(...)`\nscore = 91\nprint('Score: {:04d}'.format(score))", - "week": 4 + "week": 4, + "snippet_id": "item:kp-4-d1", + "snippet_label": "String Formatting" + }, + { + "item_id": "kp-5", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use f-strings for direct interpolation and `.format(...)` when the template string already exists; both support width, alignment, and precision specs such as `{:03d}` and `{:.2f}`.", + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" + }, + { + "item_id": "kp-5-d1", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Formatting patterns at a glance\nGoal | f-string | .format(...)\ninsert a value | f'{name}' | '{}'.format(name)\nzero-pad an int | f'{n:03d}' | '{:03d}'.format(n)\n2 decimals | f'{x:.2f}' | '{:.2f}'.format(x)", + "week": 4, + "snippet_id": "item:kp-5-d1", + "snippet_label": "String Formatting" }, { "item_id": "ai-example-1", @@ -6057,7 +7401,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Simple f-string\nname = 'Jan'\nprint(f'{name} studies Python.') # 'Jan studies Python.'\nF-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "ai-example-2", @@ -6069,7 +7415,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Debug shortcut\nval = 10\nprint(f'{val=}') # 'val=10'\nUsing f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "ai-example-3", @@ -6081,7 +7429,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Zero-padding an integer\nnum = 7\nprint(f'{num:03d}') # '007'\nYou can specify formatting after a colon, such as padding numbers with zeros.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "ai-example-4", @@ -6093,7 +7443,23 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Using `.format(...)` with placeholders\nname = 'Jan'\nscore = 7\nprint('Student {} scored {:03d}'.format(name, score))\nThe official resit material still uses `.format(...)`, so it is worth recognizing positional placeholders and width specs alongside f-strings.\nStudent Jan scored 007", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" + }, + { + "item_id": "ai-example-5", + "card_id": "w4-string-formatting", + "topic": "String Formatting", + "subtopic_id": "w4-string-formatting-core", + "subtopic_title": "f-strings Basics, Formatting, and Debug Form", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Build formatted output with custom separators\ncities = ['Amsterdam', 'Utrecht', 'Leiden']\ntext = ', '.join(cities[:-1]) + ', and ' + cities[-1]\nprint(f'Visited: {text}')\nprint('Average: {:.1f}'.format(7.25))\nWhen the output text has both repeated separators and a custom final phrase, build the list part first and then wrap it in an f-string or `.format(...)` template.\nVisited: Amsterdam, Utrecht, and Leiden\nAverage: 7.2", + "week": 4, + "snippet_id": "subtopic:w4-string-formatting:w4-string-formatting-core", + "snippet_label": "f-strings Basics, Formatting, and Debug Form" }, { "item_id": "ks-72dda5450c", @@ -6105,7 +7471,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "F-strings Basics\nF-strings (formatted string literals) allow embedding expressions inside curly braces {}. They are more readable than traditional concatenation.\nSimple f-string\nname = 'Jan'\nprint(f'{name} studies Python.') # 'Jan studies Python.'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-72dda5450c", + "snippet_label": "String Formatting" }, { "item_id": "ks-ea5a4acb43", @@ -6117,7 +7485,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "F-strings Debugging\nUsing f'{var=}' is a convenient shortcut for debugging that prints both the variable name and its value.\nDebug shortcut\nval = 10\nprint(f'{val=}') # 'val=10'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-ea5a4acb43", + "snippet_label": "String Formatting" }, { "item_id": "ks-acb7f400b2", @@ -6129,7 +7499,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "F-strings Formatting\nYou can specify formatting after a colon, such as padding numbers with zeros.\nZero-padding an integer\nnum = 7\nprint(f'{num:03d}') # '007'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-acb7f400b2", + "snippet_label": "String Formatting" }, { "item_id": "manual-self", @@ -6141,7 +7513,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Why is `self` the first parameter of an instance method?\n`self` is the current object, so the method can read and update that object's attributes.\nclass Flight:\n def set_date(self, date):\n self.date = date", - "week": 4 + "week": 4, + "snippet_id": "item:manual-self", + "snippet_label": "OOP Fundamentals" }, { "item_id": "manual-method-call", @@ -6153,7 +7527,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Why does `obj.set_date(obj, x)` pass too many arguments?\nWhen you call a method on an object, Python passes the object as `self` automatically. Writing it again adds one argument too many.\nobj.set_date(x) # correct\nobj.set_date(obj, x) # too many args", - "week": 4 + "week": 4, + "snippet_id": "item:manual-method-call", + "snippet_label": "OOP Fundamentals" }, { "item_id": "manual-init-default", @@ -6165,7 +7541,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do default values in `__init__` make constructor arguments optional?\nA default like `vehicle_mode='land'` can be omitted when the object is created, but the instance still receives that attribute value.\nclass Vehicle:\n def __init__(self, name, vehicle_mode='land'):\n self.name = name\n self.vehicle_mode = vehicle_mode", - "week": 4 + "week": 4, + "snippet_id": "item:manual-init-default", + "snippet_label": "OOP Fundamentals" }, { "item_id": "kp-1", @@ -6177,7 +7555,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "A class defines methods and attribute layout; `__init__` runs when you create an object and stores instance data on `self`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "kp-1-d1", @@ -6189,7 +7569,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Defining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color", - "week": 4 + "week": 4, + "snippet_id": "item:kp-1-d1", + "snippet_label": "OOP Fundamentals" }, { "item_id": "kp-2", @@ -6201,7 +7583,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`self` refers to the current instance, so instance methods read and write data through `self.attr`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "kp-2-d1", @@ -6213,7 +7597,37 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'", - "week": 4 + "week": 4, + "snippet_id": "item:kp-2-d1", + "snippet_label": "OOP Fundamentals" + }, + { + "item_id": "kp-manual-self-attr", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Use `self.attr = ...` to store per-object state. A bare assignment like `attr = ...` inside a method only creates or updates a local variable.", + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" + }, + { + "item_id": "kp-manual-self-attr-d1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Store state on `self`, not in a local\nclass Counter:\n def __init__(self):\n self.count = 0\n\n def bump(self):\n count = self.count + 1\n self.count = count", + "week": 4, + "snippet_id": "item:kp-manual-self-attr-d1", + "snippet_label": "OOP Fundamentals" }, { "item_id": "kp-3", @@ -6225,7 +7639,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`self.x` is per object; a class attribute is shared until an instance shadows it with its own value.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "kp-3-d1", @@ -6237,7 +7653,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Shared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1", - "week": 4 + "week": 4, + "snippet_id": "item:kp-3-d1", + "snippet_label": "OOP Fundamentals" }, { "item_id": "kp-4", @@ -6249,7 +7667,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Method calls pass `self` automatically: `obj.set_date(x)` is correct; `obj.set_date(obj, x)` passes one argument too many.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "kp-manual-init-defaults", @@ -6261,7 +7681,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Constructor defaults can make arguments optional, but mutable per-instance state should start from `None` and be created inside `__init__`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "kp-manual-init-defaults-d1", @@ -6273,7 +7695,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Optional constructor argument\nclass Vehicle:\n def __init__(self, name, mode='land'):\n self.name = name\n self.mode = mode", - "week": 4 + "week": 4, + "snippet_id": "item:kp-manual-init-defaults-d1", + "snippet_label": "OOP Fundamentals" }, { "item_id": "kp-manual-init-defaults-d2", @@ -6285,7 +7709,37 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Fresh list per object\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores", - "week": 4 + "week": 4, + "snippet_id": "item:kp-manual-init-defaults-d2", + "snippet_label": "OOP Fundamentals" + }, + { + "item_id": "kp-manual-oop-compare", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins.", + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" + }, + { + "item_id": "kp-manual-oop-compare-d1", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Comparison method template\nCase | Return\nself score > other score | winner based on `self`\nself score < other score | winner based on `other`\ntie / no clear winner | explicit fallback such as `None`", + "week": 4, + "snippet_id": "item:kp-manual-oop-compare-d1", + "snippet_label": "OOP Fundamentals" }, { "item_id": "ai-example-1", @@ -6297,7 +7751,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Defining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color\nA class defines methods and attribute layout; `__init__` runs when you create an object and stores instance data on `self`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "ai-example-2", @@ -6309,7 +7765,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "ai-example-3", @@ -6321,7 +7779,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Shared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1\n`self.x` is per object; a class attribute is shared until an instance shadows it with its own value.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "ai-example-6", @@ -6332,8 +7792,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "Subclassing `str`\n#\nclass New_str(str):\n def index(self, needle, start = 0):\n return self.find(needle, start)\n\na = New_str(\"abcd\")\nprint(a.upper()) \nprint(a.find(\"d\")) \nprint(a.find(\"e\")) \nprint(a.index(\"d\")) \nprint(a.index(\"e\"))\nYou can subclass a built-in type to add custom methods while keeping the original string behavior.", - "week": 4 + "search_text": "`self` is passed automatically in method calls\nclass Clock:\n def set_hour(self, hour):\n self.hour = hour\n\nc = Clock()\nc.set_hour(9)\n# c.set_hour(c, 9) # wrong: passes one argument too many\nWriting `obj.method(x)` already passes `self` for you. Inside the method, store lasting state on `self.attr`.", + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "manual-oop-attrs", @@ -6345,7 +7807,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Class attribute vs instance attribute\nclass Rectangle:\n units = 'cm'\n\n def __init__(self, width):\n self.width = width\n\nr1 = Rectangle(3)\nr2 = Rectangle(5)\nr2.units = 'm'\nprint(r1.units, r2.units)\n`self.width` is per object; `Class.units` is shared until an instance shadows it with its own attribute.\ncm m", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "manual-oop-init-defaults", @@ -6357,7 +7821,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state should start from `None` and be created inside `__init__`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "manual-oop-constructor-defaults", @@ -6369,7 +7835,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Constructor defaults belong in `__init__` parameters\nclass Vehicle:\n def __init__(self, name, mode=\"land\"):\n self.name = name\n self.mode = mode\n\ncar = Vehicle(\"Mazda\")\nprint(car.name, car.mode)\nDefault constructor arguments let an instance omit optional information while still giving `self` a predictable initial state.\nMazda land", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "manual-oop-state-compare", @@ -6381,7 +7849,23 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def better_than(self, other):\n return self.average() > other.average()\n\nbook_1 = Book(\"A\")\nbook_2 = Book(\"B\")\nfor score in [5, 3, 3]:\n book_1.add_review(score)\nfor score in [4, 4, 4]:\n book_2.add_review(score)\nprint(book_1.better_than(book_2))\nExam OOP reasoning often hinges on updating `self` in one method and then comparing derived state in a later method call.\nFalse", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" + }, + { + "item_id": "manual-oop-compare-none-case", + "card_id": "w4-oop-fundamentals", + "topic": "OOP Fundamentals", + "subtopic_id": "w4-oop-fundamentals-core", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Return `None` when neither object clearly wins\nclass Book:\n def __init__(self, title, scores):\n self.title = title\n self.scores = scores\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def winner_against(self, other):\n if self.average() > other.average():\n return self.title\n if self.average() < other.average():\n return other.title\n return None\nWhen an exam asks for asymmetric comparison logic, spell out both winner branches and the tie case instead of relying on one Boolean comparison only.", + "week": 4, + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics" }, { "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", @@ -6393,7 +7877,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the mode attribute should be equal to the string \"land\". Which of the following code segments achieves what you want?\nA\nB\nC\nD\nA\nIn Python, default parameter values in the __init__ method allow for optional arguments during object creation. Option A correctly assigns the parameters to instance attributes.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals" }, { "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", @@ -6405,7 +7891,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book_1.show_rating())\nA\nB\nC\nD\nA\nThe average of scores [5, 3, 3] is 11 / 3 = 3.666... Using round(..., 1) results in 3.7.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals" }, { "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", @@ -6417,7 +7905,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is also a string, but it doesn't necessarily need to be passed to the object constructor. If it isn't specified at object construction, then the \"mode\" attribute should be equal to \"land\".\n\nFor example, if we create a Vehicle object as:\nmy_car = Vehicle(\"Mazda\")\nthen the following two conditions should both be true:\nmy_car.name == \"Mazda\"\nmy_car.mode == \"land\"\n\nWhich of the following code segments achieves what you want?\na\nb\nc\nd\na\nOption A correctly uses `self` as the first parameter of the `__init__` method, provides a default value for `vehicle_mode` (\"land\"), and properly assigns both arguments to instance attributes.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals" }, { "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", @@ -6429,7 +7919,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy?\na\nb\nc\nd\na\nIn Python, when calling a method on an object, the object itself is automatically passed as the first argument (self). Passing my_flight explicitly results in too many arguments being passed to set_date.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals" }, { "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", @@ -6441,7 +7933,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the following command print to the screen?\nprint(book_1.show_rating())\na\nb\nc\nd\na\nThe list of review scores is [5, 3, 3]. The sum is 11, and the length is 3. 11 / 3 is approximately 3.666... Using `round(..., 1)` rounds this float to one decimal place, resulting in 3.7.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals" }, { "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", @@ -6453,7 +7947,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book.\n\nThe compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?\na\nb\nc\nd\nb\nOption A fails because its 'elif not avg_better:' condition triggers simply when the other book has an equal or better score, but it returns the other book's title without checking if the other book has at least as many reviews as the first book. Option B checks both pairs (self, other) and (other, self) against the requirements, returning the better one, or implicitly returning None if neither is better.", - "week": 4 + "week": 4, + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals" }, { "item_id": "ks-06b21ad349", @@ -6465,7 +7961,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Class Definition and __init__\nA class is a blueprint. The __init__ method is the constructor called automatically when a new object is created to initialize attributes.\nDefining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color", - "week": 4 + "week": 4, + "snippet_id": "item:ks-06b21ad349", + "snippet_label": "OOP Fundamentals" }, { "item_id": "ks-9e278d1ee6", @@ -6477,7 +7975,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "The self Parameter\nIn class methods, 'self' refers to the specific instance of the object. It must be the first parameter of any instance method.\nUsing self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'", - "week": 4 + "week": 4, + "snippet_id": "item:ks-9e278d1ee6", + "snippet_label": "OOP Fundamentals" }, { "item_id": "ks-5cbba26b09", @@ -6489,7 +7989,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Class vs Instance Attributes\nInstance attributes (self.x) are unique to each object. Class attributes are defined outside methods and shared by all instances of the class.\nShared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1", - "week": 4 + "week": 4, + "snippet_id": "item:ks-5cbba26b09", + "snippet_label": "OOP Fundamentals" }, { "item_id": "cs-0d319e4faf", @@ -6501,7 +8003,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "class Rectangle:\nclass Rectangle:\n total_size = 0\n def __init__(self, length, width=1):\n self.length = length\n self.width = width\n Rectangle.total_size += self.length * self.width\n print(f'{self.length} by {self.width} created, {Rectangle.total_size = }')\n def size(self, data_type=int):\n return f\"The size = {data_type(self.length * self.width)}.\"\n def __del__(self):\n Rectangle.total_size -= self.length * self.width\n print(f'{self.length} by {self.width} deleted, {Rectangle.total_size = }')\n \nprint(Rectangle.total_size)\nrectangle_1 = Rectangle(2,3) \nrectangle_2 = Rectangle(2)\ndel rectangle_1 \ndel rectangle_2\n0\n2 by 3 created, Rectangle.total_size = 6\n2 by 1 created, Rectangle.total_size = 8\n2 by 3 deleted, Rectangle.total_size = 2\n2 by 1 deleted, Rectangle.total_size = 0", - "week": 4 + "week": 4, + "snippet_id": "item:cs-0d319e4faf", + "snippet_label": "OOP Fundamentals" }, { "item_id": "cs-30e53467b8", @@ -6513,7 +8017,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "class Rectangle:\nclass Rectangle:\n total_size = 0\n def __init__(self, length, width=1):\n self.length = length\n self.width = width\n Rectangle.total_size += self.length * self.width\n print(f'rectangle {self.length} by {self.width} created\\n{Rectangle.total_size = }')\n def size(self, data_type=int):\n return f\"The size = {data_type(self.length * self.width)}.\"\n def __del__(self):\n Rectangle.total_size -= self.length * self.width\n print(f'rectangle {self.length} by {self.width} deleted\\n{Rectangle.total_size = }')\n \nprint(Rectangle.total_size)\nrectangle_1 = Rectangle(2,3)\nrectangle_2 = Rectangle(3)\nrectangle_3 = Rectangle(2,2)\n\ndel rectangle_1\ndel rectangle_3\ndel rectangle_2\n0\nrectangle 2 by 3 created\nRectangle.total_size = 6\nrectangle 3 by 1 created\nRectangle.total_size = 9\nrectangle 2 by 2 created\nRectangle.total_size = 13\nrectangle 2 by 3 deleted\nRectangle.total_size = 7\nrectangle 2 by 2 deleted\nRectangle.total_size = 3\nrectangle 3 by 1 deleted\nRectangle.total_size = 0", - "week": 4 + "week": 4, + "snippet_id": "item:cs-30e53467b8", + "snippet_label": "OOP Fundamentals" }, { "item_id": "aiq-1", @@ -6525,7 +8031,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "RuntimeError: dictionary changed size during iteration\nAdding or deleting dict entries while iterating over it causes RuntimeError", - "week": 4 + "week": 4, + "snippet_id": "item:aiq-1", + "snippet_label": "Error Handling" }, { "item_id": "kp-1", @@ -6537,7 +8045,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "The try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-error-handling:w4-error-handling-core", + "snippet_label": "try/except and raise" }, { "item_id": "kp-1-d1", @@ -6549,7 +8059,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Handling a ValueError\ns = 'abc'\ntry:\n idx = s.index('z')\nexcept ValueError:\n idx = -1", - "week": 4 + "week": 4, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Error Handling" }, { "item_id": "kp-2", @@ -6561,7 +8073,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "You can use 'raise' to manually trigger an exception when a specific condition occurs.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-error-handling:w4-error-handling-core", + "snippet_label": "try/except and raise" }, { "item_id": "kp-2-d1", @@ -6573,7 +8087,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Raising an error\ndef check_positive(n):\n if n < 0:\n raise ValueError('Number must be positive')\n return n", - "week": 4 + "week": 4, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Error Handling" }, { "item_id": "kp-3", @@ -6585,7 +8101,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Catch the specific exception you expect when you know the failure mode. `except ValueError` documents the substring-missing case more clearly than a bare `except:`.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-error-handling:w4-error-handling-core", + "snippet_label": "try/except and raise" }, { "item_id": "kp-3-d1", @@ -6597,7 +8115,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Specific exception handler\ns1 = 'abcdefghabcdefgh'\nneedle = 'i'\ntry:\n position = s1.index(needle)\nexcept ValueError:\n position = -1\nprint(position)", - "week": 4 + "week": 4, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Error Handling" }, { "item_id": "ai-example-1", @@ -6609,7 +8129,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Handling a ValueError\ns = 'abc'\ntry:\n idx = s.index('z')\nexcept ValueError:\n idx = -1\nThe try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-error-handling:w4-error-handling-core", + "snippet_label": "try/except and raise" }, { "item_id": "ai-example-2", @@ -6621,7 +8143,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Raising an error\ndef check_positive(n):\n if n < 0:\n raise ValueError('Number must be positive')\n return n\nYou can use 'raise' to manually trigger an exception when a specific condition occurs.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-error-handling:w4-error-handling-core", + "snippet_label": "try/except and raise" }, { "item_id": "ai-example-3", @@ -6633,7 +8157,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "def my_find(s,needle):\ndef my_find(s,needle):\n if (result := s.find(needle)) == -1:\n raise ValueError(\"substring not found\")\n return result\ns1 ='abcdefghabcdefgh'\nprint(my_find(s1, 'e'))\nprint(my_find(s1, 'i'))\nTrace the returned value, not just what gets printed while the function runs.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-error-handling:w4-error-handling-core", + "snippet_label": "try/except and raise" }, { "item_id": "ai-example-4", @@ -6645,7 +8171,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "def my_index(s,needle):\ndef my_index(s,needle):\n try:\n result = s.index(needle)\n except:\n result = -1\n return result\ns1 ='abcdefghabcdefgh'\nprint(my_index(s1, 'e'))\nprint(my_index(s1, 'i'))\nTrace the returned value, not just what gets printed while the function runs.", - "week": 4 + "week": 4, + "snippet_id": "subtopic:w4-error-handling:w4-error-handling-core", + "snippet_label": "try/except and raise" }, { "item_id": "ks-2c73fabc68", @@ -6657,7 +8185,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Error Handling: try-except\nThe try block lets you test a block of code for errors, and the except block lets you handle the error without the program crashing.\nHandling a ValueError\ns = 'abc'\ntry:\n idx = s.index('z')\nexcept ValueError:\n idx = -1", - "week": 4 + "week": 4, + "snippet_id": "item:ks-2c73fabc68", + "snippet_label": "Error Handling" }, { "item_id": "ks-40d373c410", @@ -6669,7 +8199,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "The raise Keyword\nYou can use 'raise' to manually trigger an exception when a specific condition occurs.\nRaising an error\ndef check_positive(n):\n if n < 0:\n raise ValueError('Number must be positive')\n return n", - "week": 4 + "week": 4, + "snippet_id": "item:ks-40d373c410", + "snippet_label": "Error Handling" }, { "item_id": "manual-series-vs-dataframe", @@ -6681,7 +8213,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What does `df['A']` return versus `df[['A']]`?\n`df['A']` returns a `Series`; `df[['A']]` returns a one-column `DataFrame`.\ndf['A']\ndf[['A']]", - "week": 5 + "week": 5, + "snippet_id": "item:manual-series-vs-dataframe", + "snippet_label": "Pandas Core Structures" }, { "item_id": "manual-series-index", @@ -6693,7 +8227,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What index does a `Series` get if you do not provide one explicitly?\nPandas uses the default integer index `0, 1, 2, ...`.\ns = pd.Series([10, 20, 30])", - "week": 5 + "week": 5, + "snippet_id": "item:manual-series-index", + "snippet_label": "Pandas Core Structures" }, { "item_id": "manual-df-constructor", @@ -6705,7 +8241,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How do you build a `DataFrame` from a dict of column names to lists?\nEach key becomes a column, and each list supplies that column's values row by row.\ndf = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})", - "week": 5 + "week": 5, + "snippet_id": "item:manual-df-constructor", + "snippet_label": "Pandas Core Structures" }, { "item_id": "kp-manual-series-default-index", @@ -6717,7 +8255,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "A `Series` is 1D labeled data; if you do not supply an index, pandas uses `0, 1, 2, ...`.", - "week": 5 + "week": 5, + "snippet_id": "item:kp-manual-series-default-index", + "snippet_label": "Pandas Core Structures" }, { "item_id": "kp-manual-df-constructor", @@ -6729,7 +8269,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "A `DataFrame` is a 2D table; a dict of column names to equal-length lists is the standard constructor pattern.", - "week": 5 + "week": 5, + "snippet_id": "item:kp-manual-df-constructor", + "snippet_label": "Pandas Core Structures" }, { "item_id": "kp-manual-series-vs-df", @@ -6740,8 +8282,52 @@ "item_type": "key_point", "bucket": "keyPoints", "selection_kind": "direct", - "search_text": "`df['A']` gives a `Series`, while `df[['A']]` gives a one-column `DataFrame`.", - "week": 5 + "search_text": "Single-column brackets return a `Series`, while a list of column names returns a `DataFrame`: `df['A']` -> Series, `df[['A']]` -> one-column DataFrame, `df[['A', 'B']]` -> two-column DataFrame.", + "week": 5, + "snippet_id": "item:kp-manual-series-vs-df", + "snippet_label": "Pandas Core Structures" + }, + { + "item_id": "kp-manual-series-vs-df-d1", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Column-selection shape rules\nCode | Returns | Why it matters\ndf['A'] | Series | one column, one bracket pair\ndf[['A']] | DataFrame | list of columns keeps 2D shape\ndf[['A', 'B']] | DataFrame | multi-column subset", + "week": 5, + "snippet_id": "item:kp-manual-series-vs-df-d1", + "snippet_label": "Pandas Core Structures" + }, + { + "item_id": "kp-manual-pandas-two-axis", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Plain `df[...]` is for column selection or a row mask. If you need both rows and columns, switch to `.loc[row_sel, col_sel]` or `.iloc[row_sel, col_sel]` instead of writing `df[row, col]`.", + "week": 5, + "snippet_id": "item:kp-manual-pandas-two-axis", + "snippet_label": "Pandas Core Structures" + }, + { + "item_id": "kp-manual-pandas-two-axis-d1", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Valid vs invalid two-axis selection\nForm | Valid? | Use for\ndf['A'] | yes | one column\ndf[['A', 'B']] | yes | multiple columns\ndf.loc[2:4, ['A']] | yes | label-based row + column selection\ndf.iloc[1:3, [0]] | yes | position-based row + column selection\ndf[2, 'A'] | no | use `.loc` or `.iloc` for two axes", + "week": 5, + "snippet_id": "item:kp-manual-pandas-two-axis-d1", + "snippet_label": "Pandas Core Structures" }, { "item_id": "manual-pandas-import", @@ -6753,7 +8339,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Import pandas with the conventional alias\nimport pandas as pd\nUse the `pd` alias so constructors and methods stay short and readable during the exam.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-pandas-core-structures:w5-pandas-core-structures-core", + "snippet_label": "Series, DataFrame, and Creation Patterns" }, { "item_id": "manual-pandas-series", @@ -6765,7 +8353,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Create a `Series` from a list\ns = pd.Series([153, 160, 150], name='Length')\nprint(s)\nWithout an explicit index, pandas labels the rows `0, 1, 2, ...`.\n0 153\n1 160\n2 150\nName: Length, dtype: int64", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-pandas-core-structures:w5-pandas-core-structures-core", + "snippet_label": "Series, DataFrame, and Creation Patterns" }, { "item_id": "manual-pandas-df", @@ -6777,7 +8367,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Build a `DataFrame` from a dict of columns\ndf = pd.DataFrame({'A': [1, 2], 'B': [3, 4]})\nprint(df)\nEach dict key becomes a column and the lists provide the row values for that column.\n A B\n0 1 3\n1 2 4", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-pandas-core-structures:w5-pandas-core-structures-core", + "snippet_label": "Series, DataFrame, and Creation Patterns" }, { "item_id": "manual-pandas-select-shape", @@ -6788,8 +8380,24 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "`df['A']` versus `df[['A']]`\ndf['A'] # Series\ndf[['A']] # one-column DataFrame\nCheck the brackets carefully: one pair returns a `Series`, two pairs return a `DataFrame`.", - "week": 5 + "search_text": "Single brackets vs list-of-columns brackets\ndf['A'] # Series\ndf[['A']] # one-column DataFrame\ndf[['A', 'B']] # two-column DataFrame\nSingle-column brackets drop to 1D `Series` shape; wrapping the column name(s) in a list keeps a 2D `DataFrame`.", + "week": 5, + "snippet_id": "subtopic:w5-pandas-core-structures:w5-pandas-core-structures-core", + "snippet_label": "Series, DataFrame, and Creation Patterns" + }, + { + "item_id": "manual-pandas-invalid-two-axis", + "card_id": "w5-pandas-core-structures", + "topic": "Pandas Core Structures", + "subtopic_id": "w5-pandas-core-structures-core", + "subtopic_title": "Series, DataFrame, and Creation Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Use `.loc` or `.iloc` for row-plus-column selection\ndf.loc[2:4, ['A']]\ndf.iloc[1:3, [0]]\n# invalid shortcut:\n# df[2, 'A']\nOnce both a row selector and a column selector appear, switch to `.loc[...]` or `.iloc[...]` instead of plain `df[...]`.", + "week": 5, + "snippet_id": "subtopic:w5-pandas-core-structures:w5-pandas-core-structures-core", + "snippet_label": "Series, DataFrame, and Creation Patterns" }, { "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", @@ -6801,7 +8409,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is performed by adding series together. Using .loc[:, 'C'] correctly assigns the result to a new column for all rows.", - "week": 5 + "week": 5, + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures" }, { "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", @@ -6813,7 +8423,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?\na\nb\nc\nd\na\nThe map() method on a Series expects a function, dictionary, or another Series. If passed a Series, it uses the values of the caller (s) to look up indices in the passed Series. This will lead to unexpected results (looking up float values like 2.0 as indices) instead of applying the mathematical transformation. The other options correctly perform the element-wise operation.", - "week": 5 + "week": 5, + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures" }, { "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", @@ -6825,7 +8437,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\na\nb\nc\nd\na\nPandas supports vectorized operations. You can add two Series (columns) together element-wise by directly using the `+` operator.", - "week": 5 + "week": 5, + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures" }, { "item_id": "ks-052ed25923", @@ -6837,7 +8451,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "pd.Series\nA one-dimensional labeled array. If no index is provided, it defaults to integers starting from 0.\nCreating a Series from a list\nimport pandas as pd\ns1 = pd.Series([153, 160, 150], name='Length')", - "week": 5 + "week": 5, + "snippet_id": "item:ks-052ed25923", + "snippet_label": "Pandas Core Structures" }, { "item_id": "ks-9a5d2c05fb", @@ -6849,7 +8465,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "pd.DataFrame\nA two-dimensional tabular data structure. Most commonly created from a dictionary where keys are column names and values are lists.\nCreating from dictionary\nd = {'Name': ['A', 'B'], 'Weight': [55, 70]}\ndf = pd.DataFrame(d, index=['First', 'Second'])", - "week": 5 + "week": 5, + "snippet_id": "item:ks-9a5d2c05fb", + "snippet_label": "Pandas Core Structures" }, { "item_id": "ks-75cf35c8b4", @@ -6861,7 +8479,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "DatetimeIndex\nA specialized index for dates. Elements have attributes like .year, .month, and .day.\nFiltering by month\ndf.loc[[r for r in df.index if r.month == 4]]", - "week": 5 + "week": 5, + "snippet_id": "item:ks-75cf35c8b4", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-82ef14b9d5", @@ -6873,7 +8493,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 4\n1 6 5\n2 7 8", - "week": 5 + "week": 5, + "snippet_id": "item:cs-82ef14b9d5", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-49cf15967e", @@ -6885,7 +8507,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 3\n1 6 4\n2 7 7", - "week": 5 + "week": 5, + "snippet_id": "item:cs-49cf15967e", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-c4c296595e", @@ -6897,7 +8521,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.loc[1] += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 2 3\n1 6 5\n2 6 7", - "week": 5 + "week": 5, + "snippet_id": "item:cs-c4c296595e", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-8bae99d6de", @@ -6909,7 +8535,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A += [1, 2]\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7", - "week": 5 + "week": 5, + "snippet_id": "item:cs-8bae99d6de", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-cdfd529b3d", @@ -6921,7 +8549,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A += [1, 2, 3]\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 3\n1 7 4\n2 9 7", - "week": 5 + "week": 5, + "snippet_id": "item:cs-cdfd529b3d", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-2e178eda82", @@ -6933,7 +8563,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.loc[[1,2]] += 1\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 2 3\n1 6 5\n2 7 8", - "week": 5 + "week": 5, + "snippet_id": "item:cs-2e178eda82", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-b3e0b57d7a", @@ -6945,7 +8577,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.A = df2.A.map(lambda x: 3 * x)\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 6 3\n1 15 4\n2 18 7", - "week": 5 + "week": 5, + "snippet_id": "item:cs-b3e0b57d7a", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-e6b6bd65f0", @@ -6957,7 +8591,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2.loc[1] = df2.loc[1].map(lambda x: 3 * x)\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 2 3\n1 15 12\n2 6 7", - "week": 5 + "week": 5, + "snippet_id": "item:cs-e6b6bd65f0", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-8ec741987c", @@ -6969,7 +8605,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 += pd.DataFrame({'A':[1, 2, 3], 'B':[4, 5, 6]})\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 3 7\n1 7 9\n2 9 13", - "week": 5 + "week": 5, + "snippet_id": "item:cs-8ec741987c", + "snippet_label": "Pandas Core Structures" }, { "item_id": "cs-b069af91f4", @@ -6981,7 +8619,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 += pd.DataFrame({'A':[2, 5, 6], 'B':[3, 4, 7]}, index=[4,5,6])\nprint(df2)\nA B\n0 2 3\n1 5 4\n2 6 7\n A B\n0 NaN NaN\n1 NaN NaN\n2 NaN NaN", - "week": 5 + "week": 5, + "snippet_id": "item:cs-b069af91f4", + "snippet_label": "Pandas Core Structures" }, { "item_id": "aiq-1", @@ -6993,7 +8633,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What happens if you run print(df.iloc[5, 2]) on a DataFrame with only 3 rows?\nUnlike slicing, accessing a specific single position with .iloc that is out of bounds raises an IndexError.\nSelection with iloc", - "week": 5 + "week": 5, + "snippet_id": "item:aiq-1", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "aiq-5", @@ -7005,7 +8647,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line", - "week": 5 + "week": 5, + "snippet_id": "item:aiq-5", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "kp-1", @@ -7017,7 +8661,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "kp-1-d1", @@ -7029,7 +8675,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Summary stats\nprint(df.describe())", - "week": 5 + "week": 5, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "kp-1-d2", @@ -7041,7 +8689,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nSelector | What it uses | Result\ndf.loc[row, col] | labels | endpoint-inclusive slicing\ndf.iloc[row, col] | positions | Python-style exclusive slice\ndf.head(n) | first rows | quick inspect\ndf[df['A'] > 0] | boolean filter | row subset", - "week": 5 + "week": 5, + "snippet_id": "item:kp-1-d2", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "kp-2", @@ -7053,7 +8703,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Label-based selection. Slicing with .loc is inclusive of the end name.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "kp-2-d1", @@ -7065,7 +8717,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Select rows/cols by name\ndf.loc['First':'Third', ['Name', 'Weight']]", - "week": 5 + "week": 5, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "kp-3", @@ -7077,7 +8731,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Integer-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists).", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "kp-3-d1", @@ -7089,7 +8745,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Select by position\ndf.iloc[0:2, 0:1] # Rows 0,1; Col 0", - "week": 5 + "week": 5, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "kp-4", @@ -7101,7 +8759,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Selecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "kp-4-d1", @@ -7113,7 +8773,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Series vs DataFrame result\ntype(df.loc[2]) # Series\ntype(df.loc[[2]]) # DataFrame", - "week": 5 + "week": 5, + "snippet_id": "item:kp-4-d1", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "kp-5", @@ -7125,7 +8787,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Filtering data by passing a mask of True/False values (often created via comparisons).", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "kp-5-d1", @@ -7137,7 +8801,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Filter by condition\ndf[df['Weight'] > 60]\ndf.loc[df.Age < 155]", - "week": 5 + "week": 5, + "snippet_id": "item:kp-5-d1", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "kp-6", @@ -7148,8 +8814,38 @@ "item_type": "key_point", "bucket": "keyPoints", "selection_kind": "direct", - "search_text": "Pattern to remember: df.loc[df.index % 2 == 0, [\"B\"]]", - "week": 5 + "search_text": "Selection rule: plain `df[...]` handles columns or a row mask, while `.loc[row_sel, col_sel]` and `.iloc[row_sel, col_sel]` handle both axes explicitly. `df[row, col]` is not the shortcut you want.", + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" + }, + { + "item_id": "kp-6-d1", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Valid vs invalid Pandas selection\nCode | Valid? | Meaning\ndf.loc[2:4, ['B']] | yes | label-based rows + columns\ndf.iloc[1:4, [1]] | yes | position-based rows + columns\ndf.loc[df['A'] > 0, ['B', 'C']] | yes | boolean-mask rows + named columns\ndf[df['A'] > 0] | yes | row filtering only\ndf[2, 'B'] | no | use `.loc` or `.iloc`", + "week": 5, + "snippet_id": "item:kp-6-d1", + "snippet_label": "Inspecting and Selecting Data" + }, + { + "item_id": "kp-6-d2", + "card_id": "w5-inspecting-and-selecting-data", + "topic": "Inspecting and Selecting Data", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Even-index row pattern\ndf.loc[df.index % 2 == 0, ['B']]", + "week": 5, + "snippet_id": "item:kp-6-d2", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "ai-example-1", @@ -7161,7 +8857,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Summary stats\nprint(df.describe())\nUse .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "ai-example-2", @@ -7173,7 +8871,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Select rows/cols by name\ndf.loc['First':'Third', ['Name', 'Weight']]\nLabel-based selection. Slicing with .loc is inclusive of the end name.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "ai-example-3", @@ -7185,7 +8885,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Select by position\ndf.iloc[0:2, 0:1] # Rows 0,1; Col 0\nInteger-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists).", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "ai-example-4", @@ -7197,7 +8899,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Series vs DataFrame result\ntype(df.loc[2]) # Series\ntype(df.loc[[2]]) # DataFrame\nSelecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "ai-example-5", @@ -7209,7 +8913,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Filter by condition\ndf[df['Weight'] > 60]\ndf.loc[df.Age < 155]\nFiltering data by passing a mask of True/False values (often created via comparisons).", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "ai-example-6", @@ -7221,7 +8927,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = [['A', 'B', 'C'],[153, 160, 150],[55, 70, 60]]\ndf1 = pd.DataFrame (d1)\ndf1 = df1.drop(1, axis = 0)\ndf1 = df1.drop(1, axis = 1)\nprint(df1)\nresult = df1.iloc[2, 2]\nprint(result)\nprint(type(result))\nDecide first whether the code is using labels (`.loc`) or integer positions (`.iloc`).\n0 2\n0 A C\n2 55 60", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "ai-example-7", @@ -7232,8 +8940,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {10:['A', 'B', 'C', 'D'], 13:[153, 160, 150, 190], 12:[55, 70, 60, 80], 17:[10, 11, 12, 13]}\ndf1 = pd.DataFrame (d1, index=[3, 2, 1, 0])\nprint(df1)\n\nprint(df1.loc[df1.loc[:,13] < 155])\nprint(df1.loc[[3,1]])\nprint(df1.iloc[::2])\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.", - "week": 5 + "search_text": "Label, mask, and step-based row selection\nimport pandas as pd\nd1 = {10:['A', 'B', 'C', 'D'], 13:[153, 160, 150, 190], 12:[55, 70, 60, 80], 17:[10, 11, 12, 13]}\ndf1 = pd.DataFrame (d1, index=[3, 2, 1, 0])\nprint(df1)\n\nprint(df1.loc[df1.loc[:,13] < 155])\nprint(df1.loc[[3,1]])\nprint(df1.iloc[::2])\nUse `.loc[...]` for label-based masks and explicit labels, and `.iloc[...]` when the selector is based on integer positions such as `::2`.", + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "ai-example-8", @@ -7244,8 +8954,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {10:['A', 'B', 'C', 'D'], 13:[153, 160, 150, 190], 12:[55, 70, 60, 80], 17:[10, 11, 12, 13]}\ndf1 = pd.DataFrame (d1, index=[3, 2, 1, 0])\nprint(df1)\n\n\nprint(df1.loc[[True, True, False, False], [False, True, False, True]])\nprint(df1.loc[[True]*2 + [False]*2, [False, True]*2])\nprint(df1.loc[[3,2], [13, 17]])\nprint(df1.iloc[:2, [1, -1]])\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.", - "week": 5 + "search_text": "Valid vs invalid indexing forms\ndf.loc[2:4, ['B']]\ndf.iloc[1:4, [1]]\ndf.loc[df['A'] > 0, ['B', 'C']]\n# invalid shortcut:\n# df[2, 'B']\nKeep the rule simple: plain `df[...]` is not the place for a row selector plus a column selector. Use `.loc` or `.iloc` when two axes are involved.", + "week": 5, + "snippet_id": "subtopic:w5-inspecting-and-selecting-data:w5-inspecting-and-selecting-data-core", + "snippet_label": "head, tail, describe, loc, iloc, Result Types, and Boolean Indexing" }, { "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", @@ -7257,7 +8969,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list to return a DataFrame. Option D would return a Series.", - "week": 5 + "week": 5, + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", @@ -7269,7 +8983,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame that only contains those elements of column \"B\" in df that have an even-numbered index. Which of the following code lines will achieve what you want?\na\nb\nc\nd\na\nOption A uses boolean indexing (`df.index % 2 == 0`) to select rows with even index values, and specifically selects column \"B\" using `.loc`.", - "week": 5 + "week": 5, + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "ks-0114a2cff0", @@ -7281,7 +8997,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Viewing Data\nUse .head(n) for the first n rows, .tail(n) for the last n rows, and .describe() for summary statistics.\nSummary stats\nprint(df.describe())", - "week": 5 + "week": 5, + "snippet_id": "item:ks-0114a2cff0", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "ks-57ff66f9f1", @@ -7293,7 +9011,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Selection: loc\nLabel-based selection. Slicing with .loc is inclusive of the end name.\nSelect rows/cols by name\ndf.loc['First':'Third', ['Name', 'Weight']]", - "week": 5 + "week": 5, + "snippet_id": "item:ks-57ff66f9f1", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "ks-dfc064979d", @@ -7305,7 +9025,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Selection: iloc\nInteger-position based selection. Slicing with .iloc is exclusive of the end index (like standard Python lists).\nSelect by position\ndf.iloc[0:2, 0:1] # Rows 0,1; Col 0", - "week": 5 + "week": 5, + "snippet_id": "item:ks-dfc064979d", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "ks-99fe849762", @@ -7317,7 +9039,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Selection Result Types\nSelecting a single row/column with a label returns a Series; using a list/slice returns a DataFrame.\nSeries vs DataFrame result\ntype(df.loc[2]) # Series\ntype(df.loc[[2]]) # DataFrame", - "week": 5 + "week": 5, + "snippet_id": "item:ks-99fe849762", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "cs-3d987070d4", @@ -7329,7 +9053,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\nd1 = [['A', 'B', 'C'],[153, 160, 150],[55, 70, 60]]\ndf1 = pd.DataFrame (d1)\ndf1 = df1.drop(1, axis = 0)\ndf1 = df1.drop(1, axis = 1)\nprint(df1)\nresult = df1.iloc[2, 2]\nprint(result)\nprint(type(result))\n0 2\n0 A C\n2 55 60", - "week": 5 + "week": 5, + "snippet_id": "item:cs-3d987070d4", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "ks-f550a3ffc7", @@ -7341,7 +9067,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Boolean Indexing\nFiltering data by passing a mask of True/False values (often created via comparisons).\nFilter by condition\ndf[df['Weight'] > 60]\ndf.loc[df.Age < 155]", - "week": 5 + "week": 5, + "snippet_id": "item:ks-f550a3ffc7", + "snippet_label": "Inspecting and Selecting Data" }, { "item_id": "aiq-1", @@ -7353,7 +9081,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Given s = pd.Series(['abc', 'xAef']), what is the result of s.str.upper().str.count('A').mean()?\nUpper becomes ['ABC', 'XAEF']. 'A' appears once in each, so counts are [1, 1]. The mean of [1, 1] is 1.0.\nVectorized Operations", - "week": 5 + "week": 5, + "snippet_id": "item:aiq-1", + "snippet_label": "Working With Values" }, { "item_id": "aiq-2", @@ -7365,7 +9095,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors", - "week": 5 + "week": 5, + "snippet_id": "item:aiq-2", + "snippet_label": "Working With Values" }, { "item_id": "aiq-3", @@ -7377,7 +9109,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: ", - "week": 5 + "week": 5, + "snippet_id": "item:aiq-3", + "snippet_label": "Working With Values" }, { "item_id": "aiq-4", @@ -7389,7 +9123,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True", - "week": 5 + "week": 5, + "snippet_id": "item:aiq-4", + "snippet_label": "Working With Values" }, { "item_id": "kp-1", @@ -7401,7 +9137,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Sort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-1-d1", @@ -7413,7 +9151,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Sorting by column values\ndf.sort_values(by='Length', ascending=False)", - "week": 5 + "week": 5, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Working With Values" }, { "item_id": "kp-2", @@ -7425,7 +9165,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Applying a scalar operation (like + or *) to an entire Series or DataFrame automatically.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-2-d1", @@ -7437,7 +9179,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Scalar broadcasting\ndf['Height'] += 10 # Adds 10 to every cell in the column", - "week": 5 + "week": 5, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Working With Values" }, { "item_id": "kp-3", @@ -7449,7 +9193,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Accessible via .str, these allow string operations on every element of a Series.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-3-d1", @@ -7461,7 +9207,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Chained string operations\ns.str.upper().str.count('A')", - "week": 5 + "week": 5, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Working With Values" }, { "item_id": "kp-4", @@ -7473,7 +9221,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "A vectorized version of 'in' to check if elements are within a collection.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-4-d1", @@ -7485,7 +9235,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Filtering with isin\nvowels = list('aeiou')\ns[s.str[-1].str.lower().isin(vowels)]", - "week": 5 + "week": 5, + "snippet_id": "item:kp-4-d1", + "snippet_label": "Working With Values" }, { "item_id": "kp-5", @@ -7496,8 +9248,10 @@ "item_type": "key_point", "bucket": "keyPoints", "selection_kind": "direct", - "search_text": "Applies a function (often a lambda) to every element of a Series.", - "week": 5 + "search_text": "Use `Series.map(f)` for elementwise work on one Series. It expects a function, dict, or mapping-style Series; for arithmetic that already works columnwise, write the vectorized expression directly instead.", + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-5-d1", @@ -7509,7 +9263,23 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Formatting with map\ndf['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g')", - "week": 5 + "week": 5, + "snippet_id": "item:kp-5-d1", + "snippet_label": "Working With Values" + }, + { + "item_id": "kp-5-d2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "`map` vs direct column arithmetic\nPattern | Best when | Example\ns.map(f) | one value in, one value out | df['W_g'] = df['Weight'].map(...)\ndf['A'] + df['B'] | plain vectorized arithmetic | df['C'] = df['A'] + df['B']\ndf.apply(f, axis=1) | row logic needs multiple columns | df.apply(lambda row: ..., axis=1)", + "week": 5, + "snippet_id": "item:kp-5-d2", + "snippet_label": "Working With Values" }, { "item_id": "kp-6", @@ -7520,8 +9290,10 @@ "item_type": "key_point", "bucket": "keyPoints", "selection_kind": "direct", - "search_text": "Applies a function along an axis (0 for columns, 1 for rows) of a DataFrame.", - "week": 5 + "search_text": "Use `DataFrame.apply(f, axis=0)` columnwise and `axis=1` rowwise. Reach for `apply` only when the function needs a whole row or column; otherwise direct column expressions are usually shorter and clearer.", + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-6-d1", @@ -7533,7 +9305,23 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Row-wise average\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)", - "week": 5 + "week": 5, + "snippet_id": "item:kp-6-d1", + "snippet_label": "Working With Values" + }, + { + "item_id": "kp-6-d2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Columnwise mean\ndf.loc['Av'] = df.apply(lambda col: col.mean(), axis=0)", + "week": 5, + "snippet_id": "item:kp-6-d2", + "snippet_label": "Working With Values" }, { "item_id": "kp-7", @@ -7545,7 +9333,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Represented by np.nan. Use .isna() to detect and .fillna() to replace them.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-7-d1", @@ -7557,7 +9347,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Handling NaNs\ndf.fillna('No value') # Replaces all NaNs", - "week": 5 + "week": 5, + "snippet_id": "item:kp-7-d1", + "snippet_label": "Working With Values" }, { "item_id": "kp-manual-drop-missing", @@ -7569,7 +9361,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use `.drop(...)` to remove labels and `.dropna()` to remove incomplete rows or columns; use `.fillna(...)` when you want to keep the shape and replace the missing values instead.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "kp-manual-drop-missing-d1", @@ -7581,7 +9375,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dropping a column by label\ndf = df.drop(1, axis=1)", - "week": 5 + "week": 5, + "snippet_id": "item:kp-manual-drop-missing-d1", + "snippet_label": "Working With Values" }, { "item_id": "kp-manual-drop-missing-d2", @@ -7593,7 +9389,51 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Removing rows with missing values\ndf.dropna()", - "week": 5 + "week": 5, + "snippet_id": "item:kp-manual-drop-missing-d2", + "snippet_label": "Working With Values" + }, + { + "item_id": "kp-manual-filter-aggregate", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Filter first, then aggregate the resulting Series or DataFrame: `sum()`, `mean()`, `count()`, and `sort_values(...)` are common exam follow-ups after a boolean mask.", + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" + }, + { + "item_id": "kp-manual-filter-aggregate-d1", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Filter then take the mean\ndf.loc[df['A'] > 0, 'B'].mean()", + "week": 5, + "snippet_id": "item:kp-manual-filter-aggregate-d1", + "snippet_label": "Working With Values" + }, + { + "item_id": "kp-manual-filter-aggregate-d2", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Common follow-up operations\nGoal | Pattern\nsum selected values | df.loc[mask, 'B'].sum()\nmean selected values | df.loc[mask, 'B'].mean()\ncount selected rows | df.loc[mask, 'B'].count()\nsort rows by a column | df.sort_values('B', ascending=False)", + "week": 5, + "snippet_id": "item:kp-manual-filter-aggregate-d2", + "snippet_label": "Working With Values" }, { "item_id": "ai-example-1", @@ -7605,7 +9445,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Sorting by column values\ndf.sort_values(by='Length', ascending=False)\nSort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "ai-example-2", @@ -7617,7 +9459,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Scalar broadcasting\ndf['Height'] += 10 # Adds 10 to every cell in the column\nApplying a scalar operation (like + or *) to an entire Series or DataFrame automatically.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "ai-example-3", @@ -7629,7 +9473,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Chained string operations\ns.str.upper().str.count('A')\nAccessible via .str, these allow string operations on every element of a Series.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "ai-example-4", @@ -7641,7 +9487,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Filtering with isin\nvowels = list('aeiou')\ns[s.str[-1].str.lower().isin(vowels)]\nA vectorized version of 'in' to check if elements are within a collection.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "ai-example-5", @@ -7653,7 +9501,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Formatting with map\ndf['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g')\nApplies a function (often a lambda) to every element of a Series.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "ai-example-6", @@ -7665,7 +9515,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Row-wise average\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)\nApplies a function along an axis (0 for columns, 1 for rows) of a DataFrame.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "manual-working-values-string-vs-map", @@ -7677,7 +9529,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`.str` methods vs `map(...)`\ns = pd.Series(['Aap', 'Nota', 'MIES'])\nprint(s.map(lambda x: x.lower()))\nprint(s.str.lower())\nUse `.str` for vectorized string operations; `map(...)` is useful when you need a custom per-value transformation.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "manual-working-values-axis-apply", @@ -7688,8 +9542,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "`apply(axis=0)` vs `apply(axis=1)`\ndf.loc['Av'] = df.apply(lambda x: x.mean(), axis=0)\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)\n`axis=0` works column by column; `axis=1` works row by row.", - "week": 5 + "search_text": "`map` vs `apply(axis=0)` vs `apply(axis=1)`\ns.map(lambda x: x * 2)\ndf.apply(lambda col: col.mean(), axis=0)\ndf.apply(lambda row: row['A'] + row['B'], axis=1)\n`map` is elementwise on one Series, `apply(..., axis=0)` works column by column, and `apply(..., axis=1)` works row by row.", + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "ai-example-7", @@ -7701,7 +9557,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Handling NaNs\ndf.fillna('No value') # Replaces all NaNs\nRepresented by np.nan. Use .isna() to detect and .fillna() to replace them.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "ai-example-8", @@ -7712,8 +9570,10 @@ "item_type": "ai_example", "bucket": "aiExamples", "selection_kind": "direct", - "search_text": "import pandas as pd\nimport pandas as pd\nd1 = {'A':[2, 5, 6], 'B':[3, 4, 7]}\ndf1 = pd.DataFrame (d1)\nprint(df1)\n\ndf2 = df1.loc[:]\ndf2 = df2.applymap(lambda x: 3 * x)\nprint(df2)\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.", - "week": 5 + "search_text": "Vectorized column arithmetic\ndf['C'] = df['A'] + df['B']\ndf['D'] = df['A'] - df['B']\nIf the exam asks for elementwise column arithmetic, direct Series expressions are usually the clearest solution and do not need `apply`.", + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "manual-pandas-split-into-columns", @@ -7725,7 +9585,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Split string data into multiple DataFrame columns\nimport pandas as pd\n\ndf = pd.DataFrame({\"place\": [\"Amsterdam; Noord-Holland\", \"Utrecht; Utrecht\"]})\ndf[[\"municipality\", \"province\"]] = df[\"place\"].str.split(\"; \", expand=True)\nprint(df)\nUse `.str.split(..., expand=True)` when the exam wants one text column unpacked into multiple DataFrame columns.\n place municipality province\n0 Amsterdam; Noord-Holland Amsterdam Noord-Holland\n1 Utrecht; Utrecht Utrecht Utrecht", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "manual-pandas-map-column-sum", @@ -7737,7 +9599,23 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Trace `map(lambda x: x + df['B'].sum())`\nimport pandas as pd\n\ndf = pd.DataFrame({\"A\": [1, 2], \"B\": [10, 20]})\nresult = df[\"A\"].map(lambda x: x + df[\"B\"].sum())\nprint(result.tolist())\n`df[\"B\"].sum()` is computed from the whole column, so each element from `A` gets the same total from `B` added to it.\n[31, 32]", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" + }, + { + "item_id": "manual-pandas-filter-aggregate", + "card_id": "w5-working-with-values", + "topic": "Working With Values", + "subtopic_id": "w5-working-with-values-core", + "subtopic_title": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Filter rows, then aggregate one column\nresult = df.loc[df['A'] > 0, 'B'].mean()\nprint(result)\nA common Pandas exam pattern is: build a boolean mask first, then run `mean()`, `sum()`, or `count()` on the selected column.", + "week": 5, + "snippet_id": "subtopic:w5-working-with-values:w5-working-with-values-core", + "snippet_label": "Sorting, Missing Data, Broadcasting, Vectorized Strings, isin, map, and apply" }, { "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", @@ -7749,7 +9627,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which of the following code lines could NOT have created df2 from df1?\nA\nB\nC\nD\nA\nOption A would sort all 5 rows of df1 and keep columns A, C, D, resulting in a 5-row DataFrame. df2 only has 3 rows (indices 4, 3, 2).", - "week": 5 + "week": 5, + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "snippet_label": "Working With Values" }, { "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", @@ -7761,7 +9641,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like splitting a string and taking the first part) to every element in a pandas Series.", - "week": 5 + "week": 5, + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values" }, { "item_id": "ks-305a41a33e", @@ -7773,7 +9655,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Sorting\nSort by labels with .sort_index() or by values with .sort_values(). axis=0 is rows, axis=1 is columns.\nSorting by column values\ndf.sort_values(by='Length', ascending=False)", - "week": 5 + "week": 5, + "snippet_id": "item:ks-305a41a33e", + "snippet_label": "Working With Values" }, { "item_id": "ks-f8eec928e1", @@ -7785,7 +9669,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Broadcasting\nApplying a scalar operation (like + or *) to an entire Series or DataFrame automatically.\nScalar broadcasting\ndf['Height'] += 10 # Adds 10 to every cell in the column", - "week": 5 + "week": 5, + "snippet_id": "item:ks-f8eec928e1", + "snippet_label": "Working With Values" }, { "item_id": "ks-115ab52188", @@ -7797,7 +9683,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Vectorized String Methods\nAccessible via .str, these allow string operations on every element of a Series.\nChained string operations\ns.str.upper().str.count('A')", - "week": 5 + "week": 5, + "snippet_id": "item:ks-115ab52188", + "snippet_label": "Working With Values" }, { "item_id": "ks-2bed6c308f", @@ -7809,7 +9697,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "isin()\nA vectorized version of 'in' to check if elements are within a collection.\nFiltering with isin\nvowels = list('aeiou')\ns[s.str[-1].str.lower().isin(vowels)]", - "week": 5 + "week": 5, + "snippet_id": "item:ks-2bed6c308f", + "snippet_label": "Working With Values" }, { "item_id": "ks-17e621a20d", @@ -7821,7 +9711,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "map()\nApplies a function (often a lambda) to every element of a Series.\nFormatting with map\ndf['W_g'] = df['Weight'].map(lambda x: f'{x*1000} g')", - "week": 5 + "week": 5, + "snippet_id": "item:ks-17e621a20d", + "snippet_label": "Working With Values" }, { "item_id": "ks-0d2d15f8d2", @@ -7833,7 +9725,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "apply()\nApplies a function along an axis (0 for columns, 1 for rows) of a DataFrame.\nRow-wise average\ndf['Avg'] = df.apply(lambda x: x.mean(), axis=1)", - "week": 5 + "week": 5, + "snippet_id": "item:ks-0d2d15f8d2", + "snippet_label": "Working With Values" }, { "item_id": "ks-18a9645168", @@ -7845,7 +9739,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Missing Data\nRepresented by np.nan. Use .isna() to detect and .fillna() to replace them.\nHandling NaNs\ndf.fillna('No value') # Replaces all NaNs", - "week": 5 + "week": 5, + "snippet_id": "item:ks-18a9645168", + "snippet_label": "Working With Values" }, { "item_id": "aiq-1", @@ -7857,7 +9753,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "During a .merge(how='left') operation, what is placed in a cell if no match is found in the right DataFrame?\nPandas uses NaN (Not a Number) to represent missing data resulting from non-overlapping joins.\nMerging", - "week": 5 + "week": 5, + "snippet_id": "item:aiq-1", + "snippet_label": "Combining Data" }, { "item_id": "kp-1", @@ -7869,7 +9767,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Gluing DataFrames together using pd.concat().", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "kp-1-d1", @@ -7881,7 +9781,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Vertical stack\npd.concat([df1, df2], axis=0)", - "week": 5 + "week": 5, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Combining Data" }, { "item_id": "kp-1-d2", @@ -7893,7 +9795,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dense reference table\nOperation | Main axis/key idea | When useful\npd.concat([...], axis=0) | stack rows | same columns\npd.concat([...], axis=1) | add columns | aligned index\ndf.merge(...) | join on key(s) | relational combine\ndf.groupby(...) | split/apply/combine | aggregate by category", - "week": 5 + "week": 5, + "snippet_id": "item:kp-1-d2", + "snippet_label": "Combining Data" }, { "item_id": "kp-2", @@ -7905,7 +9809,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Database-style joins using .merge(). 'how' determines the type (left, right, inner, outer).", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "kp-2-d1", @@ -7917,7 +9823,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Left join on a key\ndf1.merge(df2, on='Town', how='left')", - "week": 5 + "week": 5, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Combining Data" }, { "item_id": "kp-3", @@ -7929,7 +9837,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "The Split-Apply-Combine pattern using .groupby().", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "kp-3-d1", @@ -7941,7 +9851,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Grouped aggregation\ndf.groupby('Nationality')['Height'].median()", - "week": 5 + "week": 5, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Combining Data" }, { "item_id": "ai-example-1", @@ -7953,7 +9865,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Vertical stack\npd.concat([df1, df2], axis=0)\nGluing DataFrames together using pd.concat().", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "ai-example-2", @@ -7965,7 +9879,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Left join on a key\ndf1.merge(df2, on='Town', how='left')\nDatabase-style joins using .merge(). 'how' determines the type (left, right, inner, outer).", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "ai-example-3", @@ -7977,7 +9893,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Grouped aggregation\ndf.groupby('Nationality')['Height'].median()\nThe Split-Apply-Combine pattern using .groupby().", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "ai-example-4", @@ -7989,7 +9907,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noord Holland', 'Zuid Holland', 'Utrecht']})\n#print(dfprov)\n\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='left'))\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='right'))\n\ndfcombined = dftax.merge(dfprov, how='left')\ndfcombined.loc[:,'Province'] = dfcombined.loc[:,'Province'].fillna('Rest')\n# We replace the missing values with a string\n# As the groupby method ignores NaN values\nresult = dfcombined.groupby('Province')['Tax'].sum()\nresult = result.sort_values(ascending = False)\n# We want the highest paying Province first\n#print(result)\n\nprint(f\"Province {result.index[0]} has the highest tax revenue: {result[0]}\")\nprint(f\"Total tax: {result.sum()}\")\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.\nProvince Zuid Holland has the highest tax revenue: 60\nTotal tax: 100", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "ai-example-5", @@ -8001,7 +9921,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\nprint(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noord Holland', 'Zuid Holland', 'Utrecht']})\nprint(dfprov)\n\nprint(dftax.merge(dfprov, left_on='City', right_on = 'City', how='left'))\nprint(dftax.merge(dfprov, left_on='City', right_on = 'City', how='right'))\n\ndfcombined = dftax.merge(dfprov, how='left')\ndfcombined.loc[:,'Province'] = dfcombined.loc[:,'Province'].fillna('Rest')\n# We replace the missing values in the Province column with a string\n# As the groupby method ignores NaN values\nresult = dfcombined.groupby('Province')['Tax'].sum()\nresult = result.sort_values(ascending = False)\n# We want the highest paying Province first\nprint(result)\n\nprint(result[[0]])\nprint(result.sum())\nprint(result['Noord Holland'])\nUse `.loc[:, column] = ...` when the assignment should fill or update an entire column by label.", - "week": 5 + "week": 5, + "snippet_id": "subtopic:w5-combining-data:w5-combining-data-core", + "snippet_label": "Concatenation, Merging, and Grouping" }, { "item_id": "ks-591dd1aa33", @@ -8013,7 +9935,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Concatenation\nGluing DataFrames together using pd.concat().\nVertical stack\npd.concat([df1, df2], axis=0)", - "week": 5 + "week": 5, + "snippet_id": "item:ks-591dd1aa33", + "snippet_label": "Combining Data" }, { "item_id": "ks-21496ff1cd", @@ -8025,7 +9949,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Merging\nDatabase-style joins using .merge(). 'how' determines the type (left, right, inner, outer).\nLeft join on a key\ndf1.merge(df2, on='Town', how='left')", - "week": 5 + "week": 5, + "snippet_id": "item:ks-21496ff1cd", + "snippet_label": "Combining Data" }, { "item_id": "ks-f1be187b50", @@ -8037,7 +9963,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Grouping\nThe Split-Apply-Combine pattern using .groupby().\nGrouped aggregation\ndf.groupby('Nationality')['Height'].median()", - "week": 5 + "week": 5, + "snippet_id": "item:ks-f1be187b50", + "snippet_label": "Combining Data" }, { "item_id": "cs-b46633d18d", @@ -8049,7 +9977,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "import pandas as pd\nimport pandas as pd\ndftax = pd.DataFrame({'Name':['A', 'B', 'C'], 'Income':[100, 200, 150], 'Tax':[10, 60, 30], 'City':['Amsterdam', 'Rotterdam', 'London']} )\n#print(dftax)\n\ndfprov = pd.DataFrame({'City':['Amsterdam', 'Rotterdam', 'Utrecht'], 'Province': ['Noord Holland', 'Zuid Holland', 'Utrecht']})\n#print(dfprov)\n\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='left'))\n#print(dftax.merge(dfprov, left_on='City', right_on = 'City', how='right'))\n\ndfcombined = dftax.merge(dfprov, how='left')\ndfcombined.loc[:,'Province'] = dfcombined.loc[:,'Province'].fillna('Rest')\n# We replace the missing values with a string\n# As the groupby method ignores NaN values\nresult = dfcombined.groupby('Province')['Tax'].sum()\nresult = result.sort_values(ascending = False)\n# We want the highest paying Province first\n#print(result)\n\nprint(f\"Province {result.index[0]} has the highest tax revenue: {result[0]}\")\nprint(f\"Total tax: {result.sum()}\")\nProvince Zuid Holland has the highest tax revenue: 60\nTotal tax: 100", - "week": 5 + "week": 5, + "snippet_id": "item:cs-b46633d18d", + "snippet_label": "Combining Data" }, { "item_id": "aiq-1", @@ -8061,7 +9991,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Why does Python interpret {x * 2 for x in l1} as a set comprehension and not a dictionary comprehension?\nDictionary comprehensions require a 'key: value' syntax within the curly braces.\nComprehensions", - "week": 6 + "week": 6, + "snippet_id": "item:aiq-1", + "snippet_label": "Comprehensions" }, { "item_id": "aiq-2", @@ -8073,7 +10005,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions", - "week": 6 + "week": 6, + "snippet_id": "item:aiq-2", + "snippet_label": "Comprehensions" }, { "item_id": "aiq-3", @@ -8085,7 +10019,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy", - "week": 6 + "week": 6, + "snippet_id": "item:aiq-3", + "snippet_label": "Comprehensions" }, { "item_id": "aiq-4", @@ -8097,7 +10033,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function", - "week": 6 + "week": 6, + "snippet_id": "item:aiq-4", + "snippet_label": "Comprehensions" }, { "item_id": "kp-1", @@ -8109,7 +10047,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Creates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-1-d1", @@ -8121,7 +10061,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Building a set of doubled odd numbers\ns1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}", - "week": 6 + "week": 6, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Comprehensions" }, { "item_id": "kp-2", @@ -8133,7 +10075,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Since 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-2-d1", @@ -8145,7 +10089,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Double vowels in a string\ns2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python'])", - "week": 6 + "week": 6, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Comprehensions" }, { "item_id": "kp-3", @@ -8157,7 +10103,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Allows creating complex nested structures like dictionaries within dictionaries in a single concise line.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-3-d1", @@ -8169,7 +10117,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Dictionary with sub-dictionaries\nresult = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}", - "week": 6 + "week": 6, + "snippet_id": "item:kp-3-d1", + "snippet_label": "Comprehensions" }, { "item_id": "kp-4", @@ -8181,7 +10131,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "The walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-4-d1", @@ -8193,7 +10145,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Using walrus to avoid double squaring\nl1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10]", - "week": 6 + "week": 6, + "snippet_id": "item:kp-4-d1", + "snippet_label": "Comprehensions" }, { "item_id": "kp-5", @@ -8205,7 +10159,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Comprehensions are generally preferred over combining map() and filter() with lambda functions for readability.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-5-d1", @@ -8217,7 +10173,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Equivalent logic using map/filter\nl2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4])))", - "week": 6 + "week": 6, + "snippet_id": "item:kp-5-d1", + "snippet_label": "Comprehensions" }, { "item_id": "kp-6", @@ -8229,7 +10187,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Created using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-6-d1", @@ -8241,7 +10201,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Generator for large range\ngen = (x for x in range(1000000) if x % 3 == 0)", - "week": 6 + "week": 6, + "snippet_id": "item:kp-6-d1", + "snippet_label": "Comprehensions" }, { "item_id": "kp-7", @@ -8253,7 +10215,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Can include 'if' conditions to filter keys or values during dictionary creation.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-7-d1", @@ -8265,7 +10229,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Filtering dictionary items\nd = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1}", - "week": 6 + "week": 6, + "snippet_id": "item:kp-7-d1", + "snippet_label": "Comprehensions" }, { "item_id": "kp-8", @@ -8277,7 +10243,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use enumerate() to access both the index and the value of items within a comprehension.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "kp-8-d1", @@ -8289,7 +10257,37 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Divide by index plus offset\nres = [val // (i + 6) for i, val in enumerate([46, 48])]", - "week": 6 + "week": 6, + "snippet_id": "item:kp-8-d1", + "snippet_label": "Comprehensions" + }, + { + "item_id": "kp-manual-comprehension-syntax", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Read comprehension syntax left to right: output expression first, then `for`, then an optional trailing `if`; inline `a if cond else b` belongs in the output expression, not after the loop.", + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" + }, + { + "item_id": "kp-manual-comprehension-syntax-d1", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Syntax-first comprehension reference\nTarget | Template | Exam cue\nlist | [expr for x in seq if cond] | filter at the end\nlist with else | [a if cond else b for x in seq] | conditional expression stays before `for`\ndict | {key: value for x in seq} | `key: value` must appear before `for`\nset | {expr for x in seq} | curly braces without `:`\ngenerator | (expr for x in seq) | lazy, not a stored list", + "week": 6, + "snippet_id": "item:kp-manual-comprehension-syntax-d1", + "snippet_label": "Comprehensions" }, { "item_id": "ai-example-1", @@ -8301,7 +10299,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Building a set of doubled odd numbers\ns1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}\nCreates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "ai-example-2", @@ -8313,7 +10313,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Double vowels in a string\ns2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python'])\nSince 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "ai-example-3", @@ -8325,7 +10327,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Dictionary with sub-dictionaries\nresult = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}\nAllows creating complex nested structures like dictionaries within dictionaries in a single concise line.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "ai-example-4", @@ -8337,7 +10341,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Using walrus to avoid double squaring\nl1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10]\nThe walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "ai-example-5", @@ -8349,7 +10355,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Equivalent logic using map/filter\nl2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4])))\nComprehensions are generally preferred over combining map() and filter() with lambda functions for readability.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "ai-example-6", @@ -8361,7 +10369,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Generator for large range\ngen = (x for x in range(1000000) if x % 3 == 0)\nCreated using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "ai-example-7", @@ -8373,7 +10383,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Filtering dictionary items\nd = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1}\nCan include 'if' conditions to filter keys or values during dictionary creation.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "ai-example-8", @@ -8385,7 +10397,37 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Divide by index plus offset\nres = [val // (i + 6) for i, val in enumerate([46, 48])]\nUse enumerate() to access both the index and the value of items within a comprehension.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" + }, + { + "item_id": "manual-comprehension-syntax-core", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "One-line syntax reference for list, dict, and set comprehensions\nevens = [x for x in nums if x % 2 == 0]\nlabels = {name: len(name) for name in names}\nunique_lengths = {len(name) for name in names}\nThese three forms cover the main exam-recognition patterns: list output, `key: value` dict output, and set comprehensions without a colon.", + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" + }, + { + "item_id": "manual-comprehension-conditional-patterns", + "card_id": "w6-comprehensions", + "topic": "Comprehensions", + "subtopic_id": "w6-comprehensions-core", + "subtopic_title": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Filter vs transform inside a comprehension\nflipped = [letter.lower() if letter.isupper() else letter.upper() for letter in letters]\npositives = [value for value in nums if value > 0]\nUse trailing `if` to filter items out entirely; use `a if cond else b` before `for` when every input should still produce one output value.", + "week": 6, + "snippet_id": "subtopic:w6-comprehensions:w6-comprehensions-core", + "snippet_label": "List/Dict/Set Comprehensions, Nested Variants, Logic Filters, Walrus, and enumerate Patterns" }, { "item_id": "exam-intro_python_sample_final_24_25-12-w2-conditions", @@ -8397,7 +10439,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "You'd like to turn every upper case letter in a list into lower case and vice versa. Which code line achieves this?\nA\nB\nC\nD\nC\nBoth options implement the conditional logic required to flip the case of each character in the list.", - "week": 6 + "week": 6, + "snippet_id": "item:exam-intro_python_sample_final_24_25-12-w2-conditions", + "snippet_label": "Comprehensions" }, { "item_id": "ks-cacc4fbc21", @@ -8409,7 +10453,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Set Comprehensions\nCreates a set using curly braces with a single expression (not key:value pairs). Automatically handles uniqueness and ignores order.\nBuilding a set of doubled odd numbers\ns1 = {x * 2 for x in [1, 3, 2, 5] if x % 2 != 0}", - "week": 6 + "week": 6, + "snippet_id": "item:ks-cacc4fbc21", + "snippet_label": "Comprehensions" }, { "item_id": "ks-0e5c8b8b42", @@ -8421,7 +10467,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "String Transformations via List Comprehension\nSince 'string comprehensions' don't exist natively, use a list comprehension to process characters and then '.join()' them back into a string.\nDouble vowels in a string\ns2 = ''.join([x*2 if x.lower() in 'aeiou' else x for x in 'Python'])", - "week": 6 + "week": 6, + "snippet_id": "item:ks-0e5c8b8b42", + "snippet_label": "Comprehensions" }, { "item_id": "ks-3e04c4d5e8", @@ -8433,7 +10481,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Nested Dictionary Comprehensions\nAllows creating complex nested structures like dictionaries within dictionaries in a single concise line.\nDictionary with sub-dictionaries\nresult = {x: {y: x + y for y in range(x, 4)} for x in range(1, 4)}", - "week": 6 + "week": 6, + "snippet_id": "item:ks-3e04c4d5e8", + "snippet_label": "Comprehensions" }, { "item_id": "ks-b9d93f2bc1", @@ -8445,7 +10495,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Walrus Operator in Comprehensions\nThe walrus operator (:=) allows assigning a value to a variable within an expression, avoiding redundant calculations in filters or transformations.\nUsing walrus to avoid double squaring\nl1 = [(x, r) for x in range(1, 10) if 20 > (r := x**2) > 10]", - "week": 6 + "week": 6, + "snippet_id": "item:ks-b9d93f2bc1", + "snippet_label": "Comprehensions" }, { "item_id": "ks-1bc815f6d1", @@ -8457,7 +10509,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Map and Filter vs. Comprehensions\nComprehensions are generally preferred over combining map() and filter() with lambda functions for readability.\nEquivalent logic using map/filter\nl2 = list(map(lambda x: x*2, filter(lambda x: x%3 != 0, [1, 2, 3, 4])))", - "week": 6 + "week": 6, + "snippet_id": "item:ks-1bc815f6d1", + "snippet_label": "Comprehensions" }, { "item_id": "ks-0a4fcae36d", @@ -8469,7 +10523,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Generator Comprehensions\nCreated using parentheses (). Highly memory efficient because they calculate values on the fly rather than storing the whole list in memory.\nGenerator for large range\ngen = (x for x in range(1000000) if x % 3 == 0)", - "week": 6 + "week": 6, + "snippet_id": "item:ks-0a4fcae36d", + "snippet_label": "Comprehensions" }, { "item_id": "ks-72c58bb6b2", @@ -8481,7 +10537,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Dictionary Comprehensions with Logic\nCan include 'if' conditions to filter keys or values during dictionary creation.\nFiltering dictionary items\nd = {k: v for k, v in {'a': 1, 'b': 2}.items() if v > 1}", - "week": 6 + "week": 6, + "snippet_id": "item:ks-72c58bb6b2", + "snippet_label": "Comprehensions" }, { "item_id": "ks-dd2965ef50", @@ -8493,7 +10551,9 @@ "bucket": "additional", "selection_kind": "source", "search_text": "Enumerate in Comprehensions\nUse enumerate() to access both the index and the value of items within a comprehension.\nDivide by index plus offset\nres = [val // (i + 6) for i, val in enumerate([46, 48])]", - "week": 6 + "week": 6, + "snippet_id": "item:ks-dd2965ef50", + "snippet_label": "Comprehensions" }, { "item_id": "aiq-1", @@ -8505,7 +10565,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "What is the primary advantage of a generator over a list for large datasets?\nGenerators do not store the entire sequence in memory, which is essential for very large or infinite datasets.\nGenerators", - "week": 6 + "week": 6, + "snippet_id": "item:aiq-1", + "snippet_label": "Generators and Iterators" }, { "item_id": "aiq-2", @@ -8517,7 +10579,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: ", - "week": 6 + "week": 6, + "snippet_id": "item:aiq-2", + "snippet_label": "Generators and Iterators" }, { "item_id": "kp-1", @@ -8529,7 +10593,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Functions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "kp-1-d1", @@ -8541,7 +10607,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Simple step generator\ndef count(start, stop, step):\n while start <= stop:\n yield start\n start += step", - "week": 6 + "week": 6, + "snippet_id": "item:kp-1-d1", + "snippet_label": "Generators and Iterators" }, { "item_id": "kp-2", @@ -8553,7 +10621,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Objects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "kp-2-d1", @@ -8565,7 +10635,9 @@ "bucket": "keyPoints", "selection_kind": "detail", "search_text": "Manual iteration\nit = iter([1, 2]); print(next(it)); print(next(it))", - "week": 6 + "week": 6, + "snippet_id": "item:kp-2-d1", + "snippet_label": "Generators and Iterators" }, { "item_id": "ai-example-1", @@ -8577,7 +10649,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Simple step generator\ndef count(start, stop, step):\n while start <= stop:\n yield start\n start += step\nFunctions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ai-example-2", @@ -8589,7 +10663,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Manual iteration\nit = iter([1, 2]); print(next(it)); print(next(it))\nObjects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ai-example-3", @@ -8601,7 +10677,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "myiterator = iter([1,3,5])\nmyiterator = iter([1,3,5])\n\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ai-example-4", @@ -8613,7 +10691,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "class Mylist(list):\nclass Mylist(list):\n pass\nmyiterator = iter(Mylist([1,3,5]))\n\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ai-example-5", @@ -8625,7 +10705,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "mygenerator = (x for x in range(100000000) if x%3 == 0 or x%4 == 0)\nmygenerator = (x for x in range(100000000) if x%3 == 0 or x%4 == 0)\nprint(next(mygenerator))\nprint(next(mygenerator))\nprint(next(mygenerator))\nprint(next(mygenerator))\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ai-example-6", @@ -8637,7 +10719,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "class Mylist(list):\nclass Mylist(list):\n def __iter__ (self):\n pass\nmyiterator = iter(Mylist([1,3,5]))\n\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))\nprint(next(myiterator))", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ai-example-7", @@ -8649,7 +10733,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "def generatorfunction(start, stop, step):\ndef generatorfunction(start, stop, step):\n while (num:=start) <= stop:\n yield num\n start += step\n return 'End of numbers'\nfor x in generatorfunction(1, 5, 2):\n print(x)\nFor numeric variables, `a += 1` updates the stored value the same way as `a = a + 1`.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ai-example-8", @@ -8661,7 +10747,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "def generatorfunction(start, stop, step):\ndef generatorfunction(start, stop, step):\n while True:\n num = start\n start += step\n if num <= stop:\n yield num\n else:\n return 'End of numbers'\nprint(list(generatorfunction(1, 5, 2)))\nFor numeric variables, `a += 1` updates the stored value the same way as `a = a + 1`.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-generators-and-iterators:w6-generators-and-iterators-core", + "snippet_label": "Iterator Protocol, Generator Functions, and Generator Comprehensions" }, { "item_id": "ks-900b394f8e", @@ -8673,7 +10761,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Generator Functions\nFunctions using the 'yield' keyword. They produce values one at a time and maintain their local state (variables) between calls.\nSimple step generator\ndef count(start, stop, step):\n while start <= stop:\n yield start\n start += step", - "week": 6 + "week": 6, + "snippet_id": "item:ks-900b394f8e", + "snippet_label": "Generators and Iterators" }, { "item_id": "ks-cd030b9520", @@ -8685,7 +10775,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Iterators\nObjects that can be traversed using next(). Lists can be turned into iterators using iter(). They raise StopIteration when exhausted.\nManual iteration\nit = iter([1, 2]); print(next(it)); print(next(it))", - "week": 6 + "week": 6, + "snippet_id": "item:ks-cd030b9520", + "snippet_label": "Generators and Iterators" }, { "item_id": "manual-strftime-vs-strptime", @@ -8697,7 +10789,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "When do you use `strftime` versus `strptime`?\n`strftime` formats a datetime into text; `strptime` parses text into a datetime object.\ndt.strftime('%Y-%m-%d')\ndatetime.strptime('2024-05-20', '%Y-%m-%d')", - "week": 6 + "week": 6, + "snippet_id": "item:manual-strftime-vs-strptime", + "snippet_label": "Datetime" }, { "item_id": "manual-timedelta-attrs", @@ -8709,7 +10803,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "Which attributes exist directly on a `timedelta` object?\nA `timedelta` stores `days`, `seconds`, and `microseconds`; hours or weeks must be derived or supplied when constructing it.\ndelta = end - start\nprint(delta.days, delta.seconds)", - "week": 6 + "week": 6, + "snippet_id": "item:manual-timedelta-attrs", + "snippet_label": "Datetime" }, { "item_id": "manual-day-of-year", @@ -8721,7 +10817,9 @@ "bucket": "aiQuestions", "selection_kind": "direct", "search_text": "How can you compute the day number within the year from a datetime?\nSubtract January 1st of the same year, take `.days`, and add 1 so January 1st becomes day 1.\ndef day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1", - "week": 6 + "week": 6, + "snippet_id": "item:manual-day-of-year", + "snippet_label": "Datetime" }, { "item_id": "kp-manual-datetime-now", @@ -8733,7 +10831,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`datetime.now()` gives the current local datetime; use `.timestamp()` only when you specifically need seconds since the Unix epoch.", - "week": 6 + "week": 6, + "snippet_id": "item:kp-manual-datetime-now", + "snippet_label": "Datetime" }, { "item_id": "kp-manual-datetime-format", @@ -8745,7 +10845,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "`strftime` formats a datetime into text; `strptime` parses text into a datetime object.", - "week": 6 + "week": 6, + "snippet_id": "item:kp-manual-datetime-format", + "snippet_label": "Datetime" }, { "item_id": "kp-manual-datetime-delta", @@ -8757,7 +10859,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Subtracting two datetimes gives a `timedelta`; its most-used direct attributes are `.days`, `.seconds`, and `.microseconds`.", - "week": 6 + "week": 6, + "snippet_id": "item:kp-manual-datetime-delta", + "snippet_label": "Datetime" }, { "item_id": "kp-manual-datetime-replace", @@ -8769,7 +10873,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Datetime objects are immutable, so `.replace(...)` returns a new datetime instead of modifying the original one.", - "week": 6 + "week": 6, + "snippet_id": "item:kp-manual-datetime-replace", + "snippet_label": "Datetime" }, { "item_id": "kp-manual-datetime-iso", @@ -8781,7 +10887,9 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "Use `isoformat()` for an ISO-style timestamp, `isoweekday()` for Monday=1..Sunday=7, and `isocalendar()` when you need ISO year/week information.", - "week": 6 + "week": 6, + "snippet_id": "item:kp-manual-datetime-iso", + "snippet_label": "Datetime" }, { "item_id": "kp-manual-datetime-day-of-year", @@ -8793,7 +10901,65 @@ "bucket": "keyPoints", "selection_kind": "direct", "search_text": "The day number within the year can be formatted with `%j` or computed with `(dt - datetime(dt.year, 1, 1)).days + 1`.", - "week": 6 + "week": 6, + "snippet_id": "item:kp-manual-datetime-day-of-year", + "snippet_label": "Datetime" + }, + { + "item_id": "kp-manual-datetime-format-codes", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "Memorize the core format codes: `%Y` year, `%m` month, `%d` day, `%H` hour, `%M` minute, `%S` second, `%j` day-of-year.", + "week": 6, + "snippet_id": "item:kp-manual-datetime-format-codes", + "snippet_label": "Datetime" + }, + { + "item_id": "kp-manual-datetime-format-codes-d1", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Core datetime format codes\nCode | Meaning | Example\n%Y | 4-digit year | 2024\n%m | 2-digit month | 05\n%d | 2-digit day | 20\n%H | hour (24h) | 14\n%M | minute | 30\n%S | second | 09\n%j | day of year | 141", + "week": 6, + "snippet_id": "item:kp-manual-datetime-format-codes-d1", + "snippet_label": "Datetime" + }, + { + "item_id": "kp-manual-datetime-objects-vs-strings", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point", + "bucket": "keyPoints", + "selection_kind": "direct", + "search_text": "`strptime(...)` returns a `datetime`, while `strftime(...)` returns a string. Do arithmetic and attribute access on the datetime object first, then format to text at the end.", + "week": 6, + "snippet_id": "item:kp-manual-datetime-objects-vs-strings", + "snippet_label": "Datetime" + }, + { + "item_id": "kp-manual-datetime-objects-vs-strings-d1", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "", + "subtopic_title": "", + "item_type": "key_point_detail", + "bucket": "keyPoints", + "selection_kind": "detail", + "search_text": "Object vs string workflow\nOperation | Return type | Can use `.year` / `+ timedelta(...)`?\ndatetime.strptime(...) | datetime | yes\ndt.strftime(...) | str | no", + "week": 6, + "snippet_id": "item:kp-manual-datetime-objects-vs-strings-d1", + "snippet_label": "Datetime" }, { "item_id": "manual-datetime-format", @@ -8805,7 +10971,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Format a datetime with `strftime`\nfrom datetime import datetime\n\ndt = datetime(2024, 5, 20, 14, 30)\nprint(dt.strftime('%Y-%m-%d %H:%M'))\nUse `strftime` when the exam asks for a formatted string such as year-month-day or hour-minute.\n2024-05-20 14:30", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "manual-datetime-parse", @@ -8817,7 +10985,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Parse text with `strptime`\nfrom datetime import datetime\n\ndt = datetime.strptime('2024-05-20', '%Y-%m-%d')\nprint(dt)\nThe format string must match the input text exactly, including separators.\n2024-05-20 00:00:00", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "manual-datetime-delta", @@ -8829,7 +10999,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Subtract datetimes to get a `timedelta`\nfrom datetime import datetime\n\nstart = datetime(2024, 1, 1)\nend = datetime(2024, 1, 4)\nprint((end - start).days)\nDatetime subtraction gives a `timedelta`, whose `.days` attribute is often what exam questions want.\n3", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "manual-datetime-replace", @@ -8841,7 +11013,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "`.replace(...)` returns a new datetime\nfrom datetime import datetime\n\nd = datetime(2024, 5, 20)\nprint(d.replace(year=2026))\nprint(d)\nDatetime objects are immutable, so `.replace(...)` does not modify the original object in place.\n2026-05-20 00:00:00\n2024-05-20 00:00:00", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "manual-datetime-iso", @@ -8853,7 +11027,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "ISO and week-based helpers\nfrom datetime import datetime\n\nd = datetime(2024, 5, 20)\nprint(d.isoformat())\nprint(d.isoweekday())\nprint(d.isocalendar()[1])\nUse ISO helpers when the exam asks for an ISO string, the weekday with Monday as 1, or the ISO week number.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "manual-datetime-day-of-year", @@ -8865,7 +11041,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Compute the day number within the year\nfrom datetime import datetime\n\ndef day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1\n\nprint(day_of_year(datetime(2024, 5, 20)))\nSubtract January 1st of the same year, then add 1 so January 1st becomes day 1.", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "manual-datetime-overlap", @@ -8877,7 +11055,9 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Check whether two datetime intervals overlap\nfrom datetime import datetime\n\nstart_a = datetime(2024, 5, 20, 9, 0)\nend_a = datetime(2024, 5, 20, 11, 0)\nstart_b = datetime(2024, 5, 20, 10, 30)\nend_b = datetime(2024, 5, 20, 12, 0)\n\noverlaps = max(start_a, start_b) < min(end_a, end_b)\nprint(overlaps)\nA reliable overlap check compares the later start with the earlier end; there is overlap only when the later start is still before the earlier end.\nTrue", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "manual-datetime-strftime-loop", @@ -8889,7 +11069,37 @@ "bucket": "aiExamples", "selection_kind": "direct", "search_text": "Do datetime math before `strftime` turns values into strings\nfrom datetime import datetime, timedelta\n\nday = datetime(2024, 1, 1)\nlabels = []\nfor _ in range(3):\n labels.append(day.strftime(\"%Y-%m-%d\"))\n day += timedelta(days=1)\nprint(labels)\nAfter `strftime`, the value is plain text, so increment the datetime object first and only store formatted strings as the final display step.\n['2024-01-01', '2024-01-02', '2024-01-03']", - "week": 6 + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" + }, + { + "item_id": "manual-datetime-add-before-format", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Parse, do arithmetic, then format\nfrom datetime import datetime, timedelta\n\ndt = datetime.strptime('2024-05-20 14:30', '%Y-%m-%d %H:%M')\nupdated = dt + timedelta(days=2, minutes=15)\nprint(updated.strftime('%Y-%m-%d %H:%M'))\nThe safe order is parse -> work with the datetime object -> format the final answer as text.\n2024-05-22 14:45", + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" + }, + { + "item_id": "manual-datetime-year-month-day", + "card_id": "w6-datetime", + "topic": "Datetime", + "subtopic_id": "w6-datetime-core", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "item_type": "ai_example", + "bucket": "aiExamples", + "selection_kind": "direct", + "search_text": "Datetime attributes stay on the object, not on the formatted string\nfrom datetime import datetime\n\ndt = datetime.strptime('03-02-2013', '%d-%m-%Y')\nprint(dt.year, dt.month, dt.day)\nprint(dt.strftime('%Y-%m-%d'))\nAfter `strptime`, you can still read `.year`, `.month`, and `.day`; after `strftime`, you only have plain text.\n2013 2 3\n2013-02-03", + "week": 6, + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic" }, { "item_id": "exam-intro_python_sample_final_24_25-9-w6-datetime", @@ -8901,7 +11111,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Suppose that you call the function like this: get_months([\"03/02/2013\", \"03.02.2013\", \"03-02-2013\"]). What does the function call return?\nA\nB\nC\nD\nA\n1st string: contains '/' so it uses %m/%d/%Y -> month 3. 2nd: contains neither '-' nor '/' -> None. 3rd: contains '-' so it uses %d-%m-%Y -> month 2.", - "week": 6 + "week": 6, + "snippet_id": "item:exam-intro_python_sample_final_24_25-9-w6-datetime", + "snippet_label": "Datetime" }, { "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", @@ -8913,7 +11125,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 makes it 1-based (Jan 1st = day 1).", - "week": 6 + "week": 6, + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime" }, { "item_id": "ks-e643ee5e77", @@ -8925,7 +11139,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "datetime.now and Timestamps\ndatetime.now() retrieves the current local time. timestamp() returns the seconds since the Unix Epoch (Jan 1, 1970).\nGetting current timestamp\nfrom datetime import datetime\nprint(datetime.now().timestamp())", - "week": 6 + "week": 6, + "snippet_id": "item:ks-e643ee5e77", + "snippet_label": "Datetime" }, { "item_id": "ks-755c23c4be", @@ -8937,7 +11153,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "strftime: Date to String\nFormats a datetime object into a readable string using format codes (e.g., %Y for 4-digit year, %m for month).\nFormatting a date\nfrom datetime import datetime\nprint(datetime.now().strftime('%Y-%m-%d %H:%M'))", - "week": 6 + "week": 6, + "snippet_id": "item:ks-755c23c4be", + "snippet_label": "Datetime" }, { "item_id": "ks-169cc25be1", @@ -8949,7 +11167,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "strptime: String to Date\nParses a string into a datetime object based on a provided format template.\nParsing a date string\nfrom datetime import datetime\nd = datetime.strptime('2024-05-20', '%Y-%m-%d')", - "week": 6 + "week": 6, + "snippet_id": "item:ks-169cc25be1", + "snippet_label": "Datetime" }, { "item_id": "ks-86cd7ede1c", @@ -8961,7 +11181,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "Timedelta and Date Arithmetic\nTimedelta objects represent durations. Subtracting two datetimes creates a timedelta; adding a timedelta to a datetime shifts the date.\nCalculating days difference\nfrom datetime import datetime, timedelta\ndiff = datetime(2024, 1, 1) - datetime(2023, 1, 1)\nprint(diff.days)", - "week": 6 + "week": 6, + "snippet_id": "item:ks-86cd7ede1c", + "snippet_label": "Datetime" }, { "item_id": "cs-905c77e1f3", @@ -8973,7 +11195,9 @@ "bucket": "recommended", "selection_kind": "source", "search_text": "from datetime import datetime\nfrom datetime import datetime\nd = datetime.strptime(\"2024$05%20\",\"%Y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"2024*141\",\"%Y*%j\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"2024*20xyz1\",\"%Y*%Uxyz%w\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"202420Monday\",\"%Y%U%A\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"00:00:00 20-05-2024\", \"%H:%M:%S %d-%m-%Y\")\nprint(d)\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00\n2024-05-20 00:00:00", - "week": 6 + "week": 6, + "snippet_id": "item:cs-905c77e1f3", + "snippet_label": "Datetime" }, { "item_id": "ks-662456da41", @@ -8985,6 +11209,8 @@ "bucket": "additional", "selection_kind": "source", "search_text": "The replace() Method\nDatetime objects are immutable. The replace() method creates a new datetime object with specific attributes changed.\nChanging the year of a date\nfrom datetime import datetime\nd = datetime.now().replace(year=2026)", - "week": 6 + "week": 6, + "snippet_id": "item:ks-662456da41", + "snippet_label": "Datetime" } ] \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-solutions-for-python-programming-62oop21.json b/data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-solutions-for-python-programming-62oop21.json new file mode 100644 index 0000000..d19c1c6 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-solutions-for-python-programming-62oop21.json @@ -0,0 +1,8888 @@ +{ + "schema_version": "1.1", + "generated_at": "2026-03-24T10:43:09Z", + "round": "round2", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q01", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q01", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "Take a look at the following class definition.\n\nclass Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nGiven the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\nWhy?", + "options": { + "a": "The first argument (my_flight) should not have been passed to the set_date method in Code line 2.", + "b": "The capacity of the flight is not specified as an argument in Code line 1.", + "c": "The argument self is missing in Code line 1.", + "d": "The date string passed as an argument in Code line 2 represents an invalid date." + }, + "correct": "a", + "explanation": "set_date is an instance method, so Python passes self automatically. Passing my_flight explicitly adds an extra argument and causes the error.", + "code_context": "class Flight:\n def __init__(self, airline, origin, destination, capacity=300):\n self.airline = airline\n self.origin = origin\n self.destination = destination\n self.capacity = capacity\n\n def set_date(self, date):\n self.date = date\n\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\")\nmy_flight.set_date(my_flight, \"29-02-2022\")" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "kp-4", + "rationale": "Contains both a Key Point and an AI Example that explicitly use the 'set_date' method name to explain that passing the object explicitly results in 'one argument too many'." + }, + "top_three_snippets": [ + { + "item_id": "kp-4", + "rationale": "Contains both a Key Point and an AI Example that explicitly use the 'set_date' method name to explain that passing the object explicitly results in 'one argument too many'." + }, + { + "item_id": "manual-method-call", + "rationale": "Provides a direct, plain-English explanation of why calling a method with the object as the first argument causes a 'too many arguments' error." + }, + { + "item_id": "manual-self", + "rationale": "Explains the purpose of the 'self' parameter, which helps the student understand what Python is trying to pass automatically." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "kp-4", + "rationale": "The Key Point (kp-4) is the most efficient explanation available as it matches the question's method name and logic perfectly." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "This piece contains the exact class definition, code lines, and error scenario described in the question." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "Contains both a Key Point and an AI Example that explicitly use the 'set_date' method name to explain that passing the object explicitly results in 'one argument too many'.", + "critical_piece_ids": [ + "kp-4", + "ai-example-6" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:manual-method-call", + "rationale": "Provides a direct, plain-English explanation of why calling a method with the object as the first argument causes a 'too many arguments' error.", + "critical_piece_ids": [ + "manual-method-call" + ] + }, + { + "snippet_id": "item:manual-self", + "rationale": "Explains the purpose of the 'self' parameter, which helps the student understand what Python is trying to pass automatically.", + "critical_piece_ids": [ + "manual-self" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "The Key Point (kp-4) is the most efficient explanation available as it matches the question's method name and logic perfectly.", + "needed_piece_ids": [ + "kp-4" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The snippets explicitly address the specific error of passing 'self' manually. Key Point 4 even uses the exact method name 'set_date' as an example of what NOT to do.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent. No concepts are missing.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T08:28:28Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:manual-self", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-self", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Why is `self` the first parameter of an instance method?\n`self` is the current object, so the method can read and update that object's attributes.\nclass Flight:\n def set_date(self, date):\n self.date = date" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:ks-06b21ad349", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ks-06b21ad349", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Class Definition and __init__\nA class is a blueprint. The __init__ method is the constructor called automatically when a new object is created to initialize attributes.\nDefining a simple class\nclass Car:\n def __init__(self, color):\n self.color = color" + } + ] + }, + { + "snippet_id": "item:ks-9e278d1ee6", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ks-9e278d1ee6", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "The self Parameter\nIn class methods, 'self' refers to the specific instance of the object. It must be the first parameter of any instance method.\nUsing self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f" + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` is passed automatically in method calls\nclass Clock:\n def set_hour(self, hour):\n self.hour = hour\n\nc = Clock()\nc.set_hour(9)\n# c.set_hour(c, 9) # wrong: passes one argument too many\nWriting `obj.method(x)` already passes `self` for you. Inside the method, store " + }, + { + "item_id": "kp-4", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Method calls pass `self` automatically: `obj.set_date(x)` is correct; `obj.set_date(obj, x)` passes one argument too many." + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`." + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` refers to the current instance, so instance methods read and write data through `self.attr`." + }, + { + "item_id": "kp-manual-init-defaults", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Constructor defaults can make arguments optional, but mutable per-instance state should start from `None` and be created inside `__init__`." + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + } + ] + }, + { + "snippet_id": "item:manual-method-call", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-method-call", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Why does `obj.set_date(obj, x)` pass too many arguments?\nWhen you call a method on an object, Python passes the object as `self` automatically. Writing it again adds one argument too many.\nobj.set_date(x) # correct\nobj.set_date(obj, x) # too many args" + } + ] + }, + { + "snippet_id": "item:cs-0d319e4faf", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "cs-0d319e4faf", + "item_type": "source_notebook", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "class Rectangle:\nclass Rectangle:\n total_size = 0\n def __init__(self, length, width=1):\n self.length = length\n self.width = width\n Rectangle.total_size += self.length * self.width\n print(f'{self.length} by {self.width} created, {Rectangle.total_s" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:ks-5cbba26b09", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "ks-5cbba26b09", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Class vs Instance Attributes\nInstance attributes (self.x) are unique to each object. Class attributes are defined outside methods and shared by all instances of the class.\nShared class attribute\nclass Counter:\n count = 0\n def __init__(self):\n Counter.count += 1" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q02", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q02", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "OOP Fundamentals", + "question": "You have the following definition for a Book class.\n\nclass Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)\n\nSuppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews as the second book. The compare method should return the title of the better book. If neither book is better than the other, then it should return None.\n\nFor simplicity, you can assume that both books have at least one review already.\n\nWhich method definition achieves what you want?", + "options": { + "a": "def compare(self, other):\n avg_better = self.average_score() > other.average_score()\n no_fewer_reviews = self.num_reviews() >= other.num_reviews()\n if avg_better and no_fewer_reviews:\n return self.title\n elif not avg_better:\n return other.title\n else:\n return None", + "b": "def compare(self, other):\n for first, second in [(self, other), (other, self)]:\n avg_better = first.average_score() > second.average_score()\n no_fewer_reviews = first.num_reviews() >= second.num_reviews()\n if avg_better and no_fewer_reviews:\n return first.title\n return None", + "c": "Both methods above compare the book objects as intended.", + "d": "Neither of the two methods above compare the book objects as intended." + }, + "correct": "b", + "explanation": "B checks whether either book is better than the other and returns that title, otherwise it returns None. A can incorrectly return the other book even when neither book is better.", + "code_context": "class Book:\n def __init__(self, title, author):\n self.title = title\n self.author = author\n self.review_scores = []\n\n def add_review(self, score):\n self.review_scores.append(score)\n\n def num_reviews(self):\n return len(self.review_scores)\n\n def average_score(self):\n if self.num_reviews() > 0:\n return sum(self.review_scores) / len(self.review_scores)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-oop-compare-none-case", + "rationale": "This family provides the conceptual framework for object comparison, specifically handling the 'None' fallback when neither object wins and tracing state through method calls." + }, + "top_three_snippets": [ + { + "item_id": "manual-oop-compare-none-case", + "rationale": "This family provides the conceptual framework for object comparison, specifically handling the 'None' fallback when neither object wins and tracing state through method calls." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Provides the base Book class definition used in the question, helping the student understand the context of existing methods like num_reviews and average_score." + }, + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Explains the syntax of method calls and the role of 'self', which is crucial for evaluating the method definitions in the options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-oop-compare-none-case", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This piece contains the exact text and logic for the 'Book' class 'compare' method question found in the prompt." + } + ], + "best_snippet_family": { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "This family provides the conceptual framework for object comparison, specifically handling the 'None' fallback when neither object wins and tracing state through method calls.", + "critical_piece_ids": [ + "manual-oop-compare-none-case", + "kp-manual-oop-compare", + "manual-oop-state-compare" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "rationale": "Provides the base Book class definition used in the question, helping the student understand the context of existing methods like num_reviews and average_score.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Explains the syntax of method calls and the role of 'self', which is crucial for evaluating the method definitions in the options.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "rationale": "", + "needed_piece_ids": [ + "manual-oop-compare-none-case", + "kp-manual-oop-compare" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The general snippets explicitly teach the concept of returning 'None' when neither object wins (the core differentiator between A and B). Additionally, the exact question is present in the past exam items.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic of 'None' fallbacks is covered, the specific Pythonic pattern used in Option B (looping over tuple pairs to check symmetry) is not explicitly illustrated.", + "missing_concepts": [ + "Symmetric comparison using loop-over-pairs pattern" + ], + "proposed_fix": "Add an AI example showing how to check if 'either A or B wins' using a list of tuples to avoid repetitive logic." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add an AI example to 'subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core' showing: \n```python\ndef get_winner(self, other):\n for a, b in [(self, other), (other, self)]:\n if a.score > b.score:\n return a.name\n return None\n```", + "why_helpful": "This directly maps to the logic in Option B, which is a common but slightly advanced pattern for students to recognize.", + "why_maybe_unnecessary": "A student might still eliminate Option A based purely on the 'None' fallback rule already present.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T08:28:52Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "subtopic:w4-oop-fundamentals:w4-oop-fundamentals-core", + "snippet_label": "Class Definition, __init__, self, and Attribute Basics", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "manual-oop-state-compare", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Trace `self` state across multiple method calls\nclass Book:\n def __init__(self, title):\n self.title = title\n self.scores = []\n\n def add_review(self, score):\n self.scores.append(score)\n\n def average(self):\n return sum(self.scores) / len(self.sc" + }, + { + "item_id": "manual-oop-compare-none-case", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Return `None` when neither object clearly wins\nclass Book:\n def __init__(self, title, scores):\n self.title = title\n self.scores = scores\n\n def average(self):\n return sum(self.scores) / len(self.scores)\n\n def winner_against(self, other):\n if se" + }, + { + "item_id": "ai-example-6", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "`self` is passed automatically in method calls\nclass Clock:\n def set_hour(self, hour):\n self.hour = hour\n\nc = Clock()\nc.set_hour(9)\n# c.set_hour(c, 9) # wrong: passes one argument too many\nWriting `obj.method(x)` already passes `self` for you. Inside the method, store " + }, + { + "item_id": "kp-manual-oop-compare", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Comparison methods often combine state from `self` and `other`. Write the winning condition(s) explicitly, and return a clear fallback such as `None` when neither object clearly wins." + }, + { + "item_id": "manual-oop-init-defaults", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Safe default state in `__init__`\nclass Book:\n def __init__(self, title, review_scores=None):\n self.title = title\n self.review_scores = [] if review_scores is None else review_scores\nConstructor defaults can make arguments optional, but mutable per-instance state " + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "OOP Fundamentals", + "subtopic_title": "Class Definition, __init__, self, and Attribute Basics", + "search_text": "Using self to access attributes\nclass Dog:\n def __init__(self, name):\n self.name = name\n def bark(self):\n return f'{self.name} says woof!'\n`self` refers to the current instance, so instance methods read and write data through `self.attr`." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-2-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that we create a Book object and call its add_review method three times, like this: book_1 = Book(\"The Lightning Thief\", \"Rick Riordan\"), book_1.add_review(5), book_1.add_review(3), book_1.add_review(3). What will then the following command print to the screen? print(book" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q03", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q03", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].html\"\nand returns the top-level domain as a string.\n\nFor example, the function call:\nget_tld(\"https://www.uva.nl/en/education/bachelor-s/bachelors.html\")\nshould return the string:\n\"nl\"\n\nWhich of the following code segments would not achieve what you want?", + "options": { + "a": "def get_tld(url):\n url_1 = url.split(\".\")[-1]\n return url_1.split(\"/\")[0]", + "b": "def get_tld(url):\n url_1 = url.split(\"//\")[1]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]", + "c": "def get_tld(url):\n return url.split(\"//\")[1].split(\"/\")[0].split(\".\")[-1]", + "d": "def get_tld(url):\n url_1 = url[url.find(\"www\") + 2:]\n url_2 = url_1.split(\"/\")[0]\n return url_2.split(\".\")[-1]" + }, + "correct": "a", + "explanation": "A splits on the last dot first, which leaves the page extension rather than the domain. The other options isolate the host name first and then extract the final dot-separated part.", + "code_context": "def get_tld(url):\n # Extract the top-level domain from a URL string" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about URLs, this is the only other snippet that mentions processing a string with specific characters ('-') to format an output, which is conceptually closest to parsing a URL string." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about URLs, this is the only other snippet that mentions processing a string with specific characters ('-') to format an output, which is conceptually closest to parsing a URL string." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Shows a function taking two strings as inputs, which helps a novice understand the basic structure of the functions in the options." + }, + { + "item_id": "aiq-4", + "rationale": "Provides general context on return behavior, which is useful for evaluating what the functions ultimately 'return'." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Closest thematic match to string parsing." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Context for string inputs in functions." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This snippet contains the exact same question, including the URL examples and code options." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "While not about URLs, this is the only other snippet that mentions processing a string with specific characters ('-') to format an output, which is conceptually closest to parsing a URL string.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Shows a function taking two strings as inputs, which helps a novice understand the basic structure of the functions in the options.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Provides general context on return behavior, which is useful for evaluating what the functions ultimately 'return'.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Closest thematic match to string parsing.", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "Context for string inputs in functions.", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The presence of the identical past exam question makes the answer certain. However, without that specific item, the rest of the library is insufficient as it contains no explanation of .split(), .find(), or negative indexing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The library is missing explicit definitions for the string methods used in the options (split, find) and the indexing behavior ([-1]).", + "missing_concepts": [ + "str.split() and indexing the resulting list", + "str.find() behavior", + "Negative indexing ([-1])", + "String slicing ([start:])" + ], + "proposed_fix": "Add a 'String Manipulation' Key Point snippet that explains how .split() creates a list and how to access elements from it, as well as how .find() and slicing work together." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new Key Point: 'String Methods for Parsing'. Content: '1. .split(\".\") breaks a string into a list at every dot. 2. [-1] gets the last item in a list or string. 3. .find(\"sub\") returns the starting index of a substring. 4. [start:] slices from an index to the end.'", + "why_helpful": "This would allow a student to solve the problem logically rather than relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "If the goal is only to pass by memorizing past exams, the identical snippet is sufficient.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:12:06Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q04", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q04", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "Strings", + "question": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as the same letter, and whitespace characters don't count at all.\n\nFor example, the following function calls should all return the boolean value True:\nis_anagram(\"Old West Action\", \"Clint Eastwood\")\nis_anagram(\"eleven plus two\", \"twelve plus one\")\nis_anagram(\"I am a weakish speller\", \"William Shakespeare\")\n\nwhile the following function call should return the boolean value False:\nis_anagram(\"one plus two\", \"three\")\n\nWhich of the following code segments achieves what you want?", + "options": { + "a": "def is_anagram(word_1, word_2):\n return sorted(list(word_1.replace(\" \", \"\").lower())) == sorted(list(word_2.replace(\" \", \"\").lower()))", + "b": "def is_anagram(word_1, word_2):\n return word_1.replace(\" \", \"\").lower().sort() == word_2.replace(\" \", \"\").lower().sort()", + "c": "def is_anagram(word_1, word_2):\n return list(word_1.replace(\" \", \"\").lower()).sort() == list(word_2.replace(\" \", \"\").lower())", + "d": "def is_anagram(word_1, word_2):\n return sorted(list(word_1)).replace(\" \", \"\").lower() == sorted(list(word_2)).replace(\" \", \"\").lower()" + }, + "correct": "a", + "explanation": "A removes spaces, lowercases both strings, and compares the sorted letters. The other options misuse sort() or apply string operations to list objects in the wrong order.", + "code_context": "def is_anagram(word_1, word_2):\n # Compare the same letters in normalized, sorted form" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value)." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value)." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a basic context for working with lists of strings and checking conditions, though it lacks specific method details." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "rationale": "This item is an exact match for the current exam question text regarding is_anagram." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "This item is an exact match for the current exam question text regarding is_anagram." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "The only general snippet that mentions the critical concept of 'in-place mutation' for list methods, which is the key to rejecting options B and C (which use .sort() expecting a return value).", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Provides a basic context for working with lists of strings and checking conditions, though it lacks specific method details.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the direct past-exam matches, the available snippets do not explain string methods (.replace, .lower) or the return value of .sort(). A zero-knowledge student would not know that .sort() returns None, making options B/C look viable, nor would they know the order of operations for list vs string methods.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to provide the semantic details of string manipulation and the specific behavior of sorting functions vs methods.", + "missing_concepts": [ + "String methods: .replace() and .lower() (syntax and return type)", + "The difference between the sorted() function (returns new list) and the .sort() method (returns None)", + "Method chaining order: applying string methods to the result of list() will fail" + ], + "proposed_fix": "Add a reference snippet for 'Common String & List Operations' that explicitly contrasts sorted(L) with L.sort() and lists common string methods like .replace() and .lower()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: 'Python String & Sorting Basics'. Content: 'str.replace(\" \", \"\")' removes spaces; 'str.lower()' normalizes case. 'sorted(my_list)' returns a new sorted list (use for comparisons). 'my_list.sort()' returns None (do not use in comparisons).", + "why_helpful": "Directly addresses the distractors in the question by explaining why .sort() in an equality check fails.", + "why_maybe_unnecessary": "Could be considered basic language knowledge, but required for the 'zero-knowledge' target persona.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:13:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q05", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q05", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "Pandas", + "question": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 2.0\n2 3.0\n3 5.0\ndtype: float64\n\nthen you want the new Series to be:\n0 1.0\n1 1.0\n2 0.0\n3 4.0\ndtype: float64\n\nWhich of the following code segments does not achieve what you want?", + "options": { + "a": "s.map((s - s.mean())**2)", + "b": "(s - s.mean())**2", + "c": "s.map(lambda x: (x - s.mean())**2)", + "d": "(s - s.mean()).map(lambda x: x**2)" + }, + "correct": "a", + "explanation": "A is not the right way to apply the squared-difference expression to each element of the Series. B, C, and D all produce the desired squared differences.", + "code_context": "# s is a pandas Series of floats" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that the .map() method is used to apply a function, which helps identify that option (a) is incorrect because it tries to pass a Series result directly to map." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that the .map() method is used to apply a function, which helps identify that option (a) is incorrect because it tries to pass a Series result directly to map." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Introduces the concept of vectorized operations in Pandas, which explains why option (b) works." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows another example of creating a new column/Series using simple arithmetic between existing columns, reinforcing vectorization." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "This is the exact same question from a previous exam." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "Explains that the .map() method is used to apply a function, which helps identify that option (a) is incorrect because it tries to pass a Series result directly to map.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Introduces the concept of vectorized operations in Pandas, which explains why option (b) works.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows another example of creating a new column/Series using simple arithmetic between existing columns, reinforcing vectorization.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam piece provides the answer directly. Even without it, the explanation that .map() requires a function (from snippet item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals) allows a student to deduce that passing a Series calculation inside .map() is the likely error.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the map() snippet mentions it takes a function, it doesn't explicitly contrast this with vectorization or state that passing a Series to map() is a common mistake.", + "missing_concepts": [ + "Difference between vectorized operations and .map()", + "Explicit requirement of a callable for .map() versus element-wise math" + ], + "proposed_fix": "Add a conceptual snippet explaining that Pandas Series support element-wise math directly (vectorization) and that .map() specifically requires a function or dictionary as an argument." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Pandas Vectorization vs. Mapping: Use simple math operators (+, -, *, **, etc.) directly on a Series to apply that operation to every element (vectorized). Use .map(function) only when you need to apply a specific custom function to each element. Passing a Series calculation into .map() like s.map(s * 2) is invalid.", + "why_helpful": "It directly clarifies the 'trick' in the question where option A uses map incorrectly with a vectorized expression.", + "why_maybe_unnecessary": "The existing 'Applying a function' note in the map snippet might be enough for a smart student to infer the error.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:13:44Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q06", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q06", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-2", + "question": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the difference of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?", + "options": { + "a": "df[\"C\"] = df[\"A\"] - df[\"B\"]", + "b": "df[\"C\"] = df[\"A\"].map(lambda x: x - df[\"B\"])", + "c": "df[\"C\"] = df.columns[\"A\"] - df.columns[\"B\"]", + "d": "df[\"C\"] = df.apply(df[\"A\"] - df[\"B\"])" + }, + "correct": "a", + "explanation": "Subtracting one numeric Series from another directly creates the elementwise difference needed for column C.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Excluding near-identical items, this is the most helpful as it discusses the 'square of the difference between the corresponding element' in a Series, reinforcing the concept of element-wise operations." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Excluding near-identical items, this is the most helpful as it discusses the 'square of the difference between the corresponding element' in a Series, reinforcing the concept of element-wise operations." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame with columns A, B, and C, helping a student with zero knowledge visualize the data structure mentioned in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This question is structurally identical to the target question (DataFrame 'df', columns 'A', 'B', 'C'), only asking for 'sum' instead of 'difference'." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Another near-identical past question that explicitly mentions 'Vectorized addition' in its explanation, which directly translates to vectorized subtraction." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Excluding near-identical items, this is the most helpful as it discusses the 'square of the difference between the corresponding element' in a Series, reinforcing the concept of element-wise operations.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "Provides a visual example of a DataFrame with columns A, B, and C, helping a student with zero knowledge visualize the data structure mentioned in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The student can answer correctly via pattern matching using the near-identical 'sum' question, combined with the conceptual hint of 'vectorized' operations mentioned in its explanation.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While answerable through pattern matching of past exams, there is a lack of a general-purpose snippet explaining Pandas arithmetic syntax and column creation.", + "missing_concepts": [ + "Pandas vectorized arithmetic", + "Column assignment/creation syntax (df['new'] = ...)" + ], + "proposed_fix": "Add a conceptual key point snippet explaining that mathematical operators (+, -, *, /) work element-wise between Pandas Series and show the syntax for creating new columns." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point: 'Pandas Vectorized Operations: You can perform arithmetic directly on columns (e.g., df[\"C\"] = df[\"A\"] - df[\"B\"]). This performs the operation for every row automatically.'", + "why_helpful": "It moves the student from pattern matching past exams to understanding the underlying concept of vectorized operations.", + "why_maybe_unnecessary": "The near-identical exam pieces already make the question answerable for the exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:14:36Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q07", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q07", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-3", + "question": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 8.7 4.6 9.5 7.0\n2 7.3 1.5 6.3 7.1\n3 4.3 9.0 2.9 3.3\n4 4.8 2.5 5.1 3.0\n5 1.6 1.4 6.7 3.5\n6 2.4 3.7 7.6 1.3\n\nSuppose that you'd like to create a new Series that only contains those elements of column \"D\" of df that are smaller than 5.0. So the Series should look like this, when printed:\n\n3 3.3\n4 3.0\n5 3.5\n6 1.3\nName: D, dtype: float64\n\nWhich of the following code lines will not achieve what you want?", + "options": { + "a": "df.loc[2:6, df.columns[-1]]", + "b": "df.loc[df[\"D\"] < 5, \"D\"]", + "c": "df.loc[3:6, \"D\"]", + "d": "df.iloc[2:6, 3]" + }, + "correct": "a", + "explanation": "Option A slices rows 2 through 6 from the last column but does not filter out values that are 5.0 or larger, so it includes values that should not be in the result.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic DataFrame column access and vectorized operations, helping the student understand DataFrame syntax." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This piece uses the exact same DataFrame structure and a nearly identical problem statement about selecting data from column 'D'." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet demonstrates the use of .loc for selecting specific rows and columns from a DataFrame, which is central to evaluating the options in the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows basic DataFrame column access and vectorized operations, helping the student understand DataFrame syntax.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets show examples of pandas syntax, they do not explicitly define the rules for .loc (label-based, inclusive) vs .iloc (integer-based, exclusive) or how negative indexing works with columns, which are critical for distinguishing option A from the others.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide examples but lack a conceptual summary of pandas selection methods (.loc vs .iloc) and boolean indexing logic.", + "missing_concepts": [ + "Label-based vs Integer-based indexing (.loc vs .iloc)", + "Boolean indexing/filtering in Pandas", + "Slicing behavior (inclusive vs exclusive) in .loc and .iloc", + "Negative column indexing using df.columns[-1]" + ], + "proposed_fix": "Add a summary snippet for 'Pandas Inspecting and Selecting Data' that explicitly compares .loc and .iloc with examples of slicing and boolean masks." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Pandas Selection Cheat Sheet' item. Include: 1) .loc[row_label, col_label] is inclusive. 2) .iloc[row_pos, col_pos] is exclusive at the end. 3) df[df['col'] < val] filters rows. 4) df.columns[-1] refers to the last column name.", + "why_helpful": "It would allow a student to systematically check each option (a, b, c, d) against the rules rather than relying on pattern matching with other exam questions.", + "why_maybe_unnecessary": "The near-identical exam piece already provides the answer, but doesn't help with underlying understanding if the question varies slightly.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:14:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q08", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q08", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas-4", + "question": "You have two DataFrames: df1 and df2. They look like this when printed:\n\nprint(df1)\n\n Age Height Female City Language\n0 23 167 True Berlin German\n1 36 175 True Frankfurt German\n2 17 182 False Antwerpen Dutch\n3 25 177 True Eindhoven Dutch\n4 36 178 False Lyon French\n5 52 185 False Basel German\n6 46 168 True Innsbruck German\n\nprint(df2)\n\n Age Height Female City Language\n5 52 185 False Basel German\n4 36 178 False Lyon French\n1 36 175 True Frankfurt German\n6 46 168 True Innsbruck German\n0 23 167 True Berlin German\n\nWhich of the following code segments could have created df2 from df1?", + "options": { + "a": "df1.loc[df1[\"Language\"].isin([\"French\", \"German\"])].sort_values(\"Height\", ascending=False)", + "b": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_values(\"Age\", ascending=False)", + "c": "df1.loc[~df1[\"Language\"].isin([\"Dutch\"]), [\"Age\", \"Height\", \"City\", \"Language\"]].sort_index(ascending=False)", + "d": "df1.loc[df1[\"Language\"] != \"Dutch\"].sort_index(axis=1)" + }, + "correct": "a", + "explanation": "Option A filters out the Dutch rows and then sorts the remaining rows by Height in descending order, matching df2 exactly.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides basic context on pandas DataFrame operations and column-based logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet explicitly deals with the topic of inspecting and selecting data from a pandas DataFrame, which is the core requirement of the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Provides basic context on pandas DataFrame operations and column-based logic.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The available snippets only mention 'Inspecting and Selecting Data' but do not provide the syntax or behavior for .isin(), .sort_values(), or .sort_index(). A student without prior knowledge would not be able to distinguish between the sorting and filtering methods used in the options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing critical documentation on pandas filtering (isin) and sorting (sort_values/sort_index).", + "missing_concepts": [ + "pandas.Series.isin()", + "pandas.DataFrame.sort_values()", + "pandas.DataFrame.sort_index()", + "Boolean indexing on string columns" + ], + "proposed_fix": "Add a dedicated snippet for 'Pandas Sorting and Filtering' that includes examples of selecting rows based on categories (isin) and reordering rows by column values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet family 'Pandas: Filtering and Sorting' with a piece demonstrating: 1. df[df['col'].isin(['val1', 'val2'])], 2. df.sort_values('col', ascending=False), and 3. df.sort_index().", + "why_helpful": "This directly covers the specific methods tested in this exam question, allowing a student to identify that Option A uses the correct filtering and sorting logic.", + "why_maybe_unnecessary": "If the student already knows basic pandas, they might guess based on English names, but it's not robust for a 'zero knowledge' use case.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:15:20Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q09", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q09", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-1", + "question": "You have a list of mountain peaks and their heights in meters, all formatted as \"[PEAK NAME]: [HEIGHT]m\". For example, a few elements of the list are:\n\"Denali: 6,190m\", \"Aconcagua: 6,961m\", \"Kilimanjaro: 5,895m\", ...\n\nAs you can see, the comma (\",\") is used as a thousand separator in the height. The list is called mountains.\n\nYou'd like to create a dictionary called peaks from the mountains list. The peak names would be the keys, and the corresponding integer values. Continuing the example above, a few key-value pairs of the peaks dictionary should be:\n\"Denali\": 6190, \"Aconcagua\": 6961, \"Kilimanjaro\": 5895, ...\n\nWhich of the following two code segments achieves what you want?", + "options": { + "a": "peaks = {peak.split(\":\")[0]: int(peak.split(\": \")[1][:-1].replace(\",\", \"\")) for peak in mountains}", + "b": "names = [peak.split(\":\")[0] for peak in mountains]\nheights = [int(peak.split(\": \")[1].replace(\",\", \"\").replace(\"m\", \"\")) for peak in mountains]\npeaks = dict(zip(names, heights))", + "c": "Both code segments above achieve the intended outcome.", + "d": "Neither of the two code segments above achieves the intended outcome." + }, + "correct": "c", + "explanation": "Both solutions strip off the trailing m, remove the thousands separator, convert the height to an integer, and pair each mountain name with its numeric height.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates creating a dictionary from two separate lists (names and values), which confirms the validity of the structural pattern used in Option B." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides a conceptual precedent for extracting specific substrings (like a TLD) from a larger formatted string, mirroring the task of parsing names and heights." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet directly demonstrates the syntax for a dictionary comprehension used to transform a list of strings into a dictionary, which is the core logic in Option A.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates creating a dictionary from two separate lists (names and values), which confirms the validity of the structural pattern used in Option B.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Provides a conceptual precedent for extracting specific substrings (like a TLD) from a larger formatted string, mirroring the task of parsing names and heights.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide strong structural evidence that both Code Segment A (dictionary comprehension) and Code Segment B (zip/dict) are valid Python patterns for creating dictionaries. However, a student with zero prior knowledge would still struggle to verify the 'string cleaning' logic (split, replace, slicing) as none of the snippets explicitly show these methods in action.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Structural dictionary patterns are well-covered, but the specific string manipulation methods required to 'clean' the data are missing.", + "missing_concepts": [ + "String .split() method", + "String .replace() method", + "String slicing syntax (e.g., [:-1])", + "The use of int() for converting numeric strings" + ], + "proposed_fix": "Add a reference snippet or past exam item that explicitly uses .split(), .replace(), and slicing to parse strings." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'String Cleaning' reference snippet: 'text.split(\": \")[1]' extracts data after a colon, 'text.replace(\",\", \"\")' removes characters, and 'text[:-1]' removes the last character (like 'm').", + "why_helpful": "This allows a zero-knowledge student to confirm that the complex-looking expressions inside the comprehensions actually perform the specific cleanup described in the question.", + "why_maybe_unnecessary": "The student might guess the meaning of .replace() or .split() based on common English definitions, but precise confirmation is better for 'certain' answerability.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:15:55Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q10", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q10", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "8-comprehensions-2", + "question": "You have a dictionary called grades, in which the keys are unique student ID's (as strings) and the corresponding values are each student's Python course grades (as floats).\n\nYou'd like to create another dictionary called grade_curve, in which the keys are the 18 possible Dutch course grades (1.0, 1.5, 2.0, ..., 10) as floats, and the corresponding (integer) values are the number of students in grades who have that particular grade.\n\nTake a look at the following code segment to create the grade_curve dictionary.\n\ndutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0,\n 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}\n\nDo you think this code segment will always work as intended? If not, then why not?", + "options": { + "a": "Yes, the code will always work as intended.", + "b": "The code will not work as intended if there are certain grades that no student has received. That will lead to an error in constructing the dictionary comprehension.", + "c": "The code will not work as intended, because the keys of the grades dictionary are not used in the list comprehension inside the sum function.", + "d": "The code will not work as intended, because including a list comprehension inside a dictionary comprehension will lead to a Python syntax error." + }, + "correct": "a", + "explanation": "The inner comparison list produces True and False values for every grade entry, and sum counts the matches, including zero when no student received that grade.", + "code_context": "dutch_grades = [1.0, 1.5, 2.0, 2.5, 3.0, 3.5, 4.0, 4.5, 5.0, 6.0, 6.5, 7.0, 7.5, 8.0, 8.5, 9.0, 9.5, 10.0]\ngrade_curve = {grade: sum([v == grade for v in grades.values()]) for grade in dutch_grades}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the syntax and validity of dictionary comprehensions, which helps rule out option (d)." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Provides another example of generating a dictionary from a sequence using logic in a comprehension." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "This snippet directly addresses the task of creating a dictionary that counts occurrences of grades, mirroring the logic of the exam question.", + "critical_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the syntax and validity of dictionary comprehensions, which helps rule out option (d).", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Provides another example of generating a dictionary from a sequence using logic in a comprehension.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets show that dictionary comprehensions are a standard and valid way to count items or transform lists into dictionaries. However, none explicitly explain that 'sum()' on a list of booleans converts True to 1 and False to 0, which is the specific mechanism used in the question's code.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets confirm that the syntax is valid (ruling out d) and that dictionary counting is a common pattern. However, the specific behavior of sum() with booleans and the fact that an empty match returns 0 rather than an error is not explicitly covered.", + "missing_concepts": [ + "sum() behavior with Boolean values (True=1, False=0)", + "Behavior of comprehensions when no items match a condition (returns 0 for sum of empty/false list)" + ], + "proposed_fix": "Add a snippet or detail explaining how Python handles boolean arithmetic and summing lists of comparison results." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet explaining that in Python, True behaves like 1 and False like 0 when used in mathematical functions like sum(). Example: sum([True, False, True]) == 2.", + "why_helpful": "This is the core concept required to understand why the provided code segment 'always works' and doesn't produce an error when a grade has zero matches.", + "why_maybe_unnecessary": "Students might have learned that booleans are integers in an earlier lecture, but it is a common 'trick' question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:16:18Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "students = ['A','B','C','D','E','F']\ngrades = [9,10,9,11,10,9]\n\nYou need to create a dictionary called grade_counts that counts the number of students in each grade level.\n\nExpected: {9:3, 10:2, 11:1}\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption a" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2024-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following a dictionary called students, which contains three sub-dictionaries:\nstudents = {\"james\": {\"name\": \"James\",\n\"homework\": [90.0, 97.0, 75.0, 92.0],\n\"quizzes\": [88.0, 40.0, 94.0],\n\"tests\": [75.0, 90.0]},\n\"eva\": {\"name\": \"Eva\",\n\"homework\": [100.0, 92." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q11", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q11", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-1", + "question": "What does the following code segment print to the screen?\n\nfrom datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))", + "options": { + "a": "26-03-2020", + "b": "04-24-2020", + "c": "15-04-2020", + "d": "05-14-2020" + }, + "correct": "a", + "explanation": "The string is parsed as 5 April 2020 using month.day.year format, and subtracting 10 days yields 26 March 2020, which is then formatted as day-month-year.", + "code_context": "from datetime import datetime, timedelta\n\ndate = datetime.strptime(\"04.05.2020\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "manual-datetime-add-before-format", + "rationale": "This family contains an AI example ('manual-datetime-add-before-format') that follows the exact logical flow of the question: parse a string, perform arithmetic with timedelta, and format the result back into a string." + }, + "top_three_snippets": [ + { + "item_id": "manual-datetime-add-before-format", + "rationale": "This family contains an AI example ('manual-datetime-add-before-format') that follows the exact logical flow of the question: parse a string, perform arithmetic with timedelta, and format the result back into a string." + }, + { + "item_id": "ks-755c23c4be", + "rationale": "Provides explicit definitions for %m (month) and %Y (year), which are crucial for the student to correctly identify that '04' is the month in the input string." + }, + { + "item_id": "cs-905c77e1f3", + "rationale": "Demonstrates strptime with various custom separators, helping the student understand how the format string ('%m.%d.%Y') maps to the input string ('04.05.2020')." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "manual-datetime-add-before-format", + "rationale": "" + }, + { + "item_id": "ks-755c23c4be", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "rationale": "This family contains an AI example ('manual-datetime-add-before-format') that follows the exact logical flow of the question: parse a string, perform arithmetic with timedelta, and format the result back into a string.", + "critical_piece_ids": [ + "manual-datetime-add-before-format", + "manual-datetime-format" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-755c23c4be", + "rationale": "Provides explicit definitions for %m (month) and %Y (year), which are crucial for the student to correctly identify that '04' is the month in the input string.", + "critical_piece_ids": [ + "ks-755c23c4be" + ] + }, + { + "snippet_id": "item:cs-905c77e1f3", + "rationale": "Demonstrates strptime with various custom separators, helping the student understand how the format string ('%m.%d.%Y') maps to the input string ('04.05.2020').", + "critical_piece_ids": [ + "cs-905c77e1f3" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "rationale": "", + "needed_piece_ids": [ + "manual-datetime-add-before-format" + ] + }, + { + "snippet_id": "item:ks-755c23c4be", + "rationale": "", + "needed_piece_ids": [ + "ks-755c23c4be" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the 'Parse, do arithmetic, then format' AI example and the definition of format codes in the lecture snippet covers every step required to solve the question without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are highly effective, though %d (day) is only implicitly shown rather than explicitly defined.", + "missing_concepts": [ + "Explicit definition of the %d format code" + ], + "proposed_fix": "Enhance the lecture or AI snippet to include a concise table of the most common format codes (%d, %m, %Y, %H, %M)." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-755c23c4be", + "proposal": "Update the description of format codes to explicitly list %d as 'day of month (01-31)'.", + "why_helpful": "Reduces the need for the student to guess that %d stands for day, especially when the date '04.05' could be ambiguous (Month.Day vs Day.Month) if codes aren't known.", + "why_maybe_unnecessary": "The student can likely infer the meaning from the surrounding code and the options provided.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:16:47Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:ks-86cd7ede1c", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "ks-86cd7ede1c", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Timedelta and Date Arithmetic\nTimedelta objects represent durations. Subtracting two datetimes creates a timedelta; adding a timedelta to a datetime shifts the date.\nCalculating days difference\nfrom datetime import datetime, timedelta\ndiff = datetime(2024, 1, 1) - datetime(2023, " + } + ] + }, + { + "snippet_id": "subtopic:w6-datetime:w6-datetime-core", + "snippet_label": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "manual-datetime-add-before-format", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Parse, do arithmetic, then format\nfrom datetime import datetime, timedelta\n\ndt = datetime.strptime('2024-05-20 14:30', '%Y-%m-%d %H:%M')\nupdated = dt + timedelta(days=2, minutes=15)\nprint(updated.strftime('%Y-%m-%d %H:%M'))\nThe safe order is parse -> work with the datetime object" + }, + { + "item_id": "manual-datetime-day-of-year", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Compute the day number within the year\nfrom datetime import datetime\n\ndef day_of_year(dt):\n return (dt - datetime(dt.year, 1, 1)).days + 1\n\nprint(day_of_year(datetime(2024, 5, 20)))\nSubtract January 1st of the same year, then add 1 so January 1st becomes day 1." + }, + { + "item_id": "manual-datetime-delta", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Subtract datetimes to get a `timedelta`\nfrom datetime import datetime\n\nstart = datetime(2024, 1, 1)\nend = datetime(2024, 1, 4)\nprint((end - start).days)\nDatetime subtraction gives a `timedelta`, whose `.days` attribute is often what exam questions want.\n3" + }, + { + "item_id": "manual-datetime-replace", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "`.replace(...)` returns a new datetime\nfrom datetime import datetime\n\nd = datetime(2024, 5, 20)\nprint(d.replace(year=2026))\nprint(d)\nDatetime objects are immutable, so `.replace(...)` does not modify the original object in place.\n2026-05-20 00:00:00\n2024-05-20 00:00:00" + }, + { + "item_id": "manual-datetime-strftime-loop", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Do datetime math before `strftime` turns values into strings\nfrom datetime import datetime, timedelta\n\nday = datetime(2024, 1, 1)\nlabels = []\nfor _ in range(3):\n labels.append(day.strftime(\"%Y-%m-%d\"))\n day += timedelta(days=1)\nprint(labels)\nAfter `strftime`, the value is p" + }, + { + "item_id": "manual-datetime-format", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Datetime", + "subtopic_title": "now, Timestamps, strftime, strptime, timedelta, and Date Arithmetic", + "search_text": "Format a datetime with `strftime`\nfrom datetime import datetime\n\ndt = datetime(2024, 5, 20, 14, 30)\nprint(dt.strftime('%Y-%m-%d %H:%M'))\nUse `strftime` when the exam asks for a formatted string such as year-month-day or hour-minute.\n2024-05-20 14:30" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:ks-755c23c4be", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "ks-755c23c4be", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "strftime: Date to String\nFormats a datetime object into a readable string using format codes (e.g., %Y for 4-digit year, %m for month).\nFormatting a date\nfrom datetime import datetime\nprint(datetime.now().strftime('%Y-%m-%d %H:%M'))" + } + ] + }, + { + "snippet_id": "item:cs-905c77e1f3", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "cs-905c77e1f3", + "item_type": "source_notebook", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "from datetime import datetime\nfrom datetime import datetime\nd = datetime.strptime(\"2024$05%20\",\"%Y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\nprint(d)\n\nfrom datetime import datetime\nd = datetime.strptime(\"24$05%20\",\"%y$%m%%%d\")\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q12", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q12", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "8-datetime-2", + "question": "Suppose you have the following definition for a Meeting class, which records basic information about meetings in a calendar application.\n\nYou would like to add a method called lunch_meeting to this class, which returns a boolean value indicating whether there is any overlap between the official lunchtime (12:30 - 13:00) and the time of the meeting.\n\nFor example, if you construct a Meeting object as:\nmy_meeting = Meeting('Ask for salary raise', \"25-05-2022\", start_time='12:00', length=45)\nthen the method call:\nmy_meeting.lunch_meeting()\nshould return the boolean value True.\n\nWhich of the following code segments will achieve what you want?", + "options": { + "a": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = lunch_start + timedelta(minutes=30)\n return self.start < lunch_end and self.end > lunch_start", + "b": "def lunch_meeting(self):\n return self.start < \"13:00\" and self.end > \"12:30\"", + "c": "def lunch_meeting(self):\n return start_time <= \"13:00\" and start_time + length > \"12:30\"", + "d": "def lunch_meeting(self):\n lunch_start = datetime(self.date.year, self.date.month, self.date.day, 12, 30)\n lunch_end = datetime(self.date.year, self.date.month, self.date.day, 13, 0)\n return self.start >= lunch_end or self.end <= lunch_start" + }, + "correct": "a", + "explanation": "Option A constructs the lunch interval on the same date and uses the standard interval-overlap check. The other options compare datetimes to strings, reference names that are not in scope, or use the non-overlap condition instead.", + "code_context": "from datetime import datetime, timedelta\n\nclass Meeting:\n def __init__(self, topic, date, start_time=\"09:00\", length=30):\n self.topic = topic\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day,\n int(start_time.split(':')[0]), int(start_time.split(':')[1]))\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining classes and initializing attributes, which helps the student understand the 'Meeting' class context." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet shows the implementation of a class method ('compare') that interacts with other objects/attributes, providing the closest structural template for adding 'lunch_meeting' to the 'Meeting' class.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining classes and initializing attributes, which helps the student understand the 'Meeting' class context.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets mention the 'datetime' or 'timedelta' modules. A student with zero prior knowledge would not know how to construct a datetime object using 'datetime(year, month, day, hour, minute)', how to add time using 'timedelta', or how to compare datetime objects. The logic for interval overlap is also not explained.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets provided focus on basic OOP and Pandas, completely missing the Week 8 'datetime' content required for this question.", + "missing_concepts": [ + "datetime module syntax (datetime constructor)", + "timedelta for time arithmetic", + "Datetime comparison operators (<, >)", + "General logic for checking overlapping time intervals" + ], + "proposed_fix": "Add a new snippet for the datetime module that explains how to create timestamps and add durations, specifically including the standard interval overlap logic: (start1 < end2 and end1 > start2)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Working with Datetimes'. Content: 'from datetime import datetime, timedelta'. Explain: 'datetime(year, month, day, hour, minute)' creates a point in time. 'timedelta(minutes=30)' represents a duration. Datetimes can be compared with < and >. Logic: Two intervals (start1, end1) and (start2, end2) overlap if 'start1 < end2 and end1 > start2'.", + "why_helpful": "This provides the specific library syntax and the mathematical logic needed to identify Option A as correct and others as incorrect.", + "why_maybe_unnecessary": "Only if the student is expected to already have these library details from a general Python reference, but the goal is to help those with 'almost zero' knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:17:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q13", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q13", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "Basic logic 2", + "question": "Suppose you have a variable x which contains a list of tuples, as follows:\n\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nChoose the correct output for the following line of code.\n\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])", + "options": { + "a": "True", + "b": "False", + "c": "NameError", + "d": "SyntaxError" + }, + "correct": "a", + "explanation": "The left-hand side is 2 * 3 = 6 and the right-hand side is 8 - 2 = 6, so the comparison evaluates to True.", + "code_context": "x = [(1, 2), (3, 4), (5, 6), (7, 8)]\n(x[0][1] * x[-3][0]) == (x[-1][1] - x[-4][1])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "While technically a different topic, this snippet provides the most explicit example of list/string indexing syntax `[1::2]` and implied indexing logic, which is the core concept needed if the direct exam matches were excluded." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "While technically a different topic, this snippet provides the most explicit example of list/string indexing syntax `[1::2]` and implied indexing logic, which is the core concept needed if the direct exam matches were excluded." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Shows list manipulation and the result of extraction/sorting, helping a student understand how Python handles collections." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "Matches the exact variable `x = [(1, 2), (3, 4), (5, 6), (7, 8)]` and explains the evaluation of `2 * 3 == 6`." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Identical logic and explanation for a list of tuples named x, confirming the arithmetic result." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "While technically a different topic, this snippet provides the most explicit example of list/string indexing syntax `[1::2]` and implied indexing logic, which is the core concept needed if the direct exam matches were excluded.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Shows list manipulation and the result of extraction/sorting, helping a student understand how Python handles collections.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets include the exact question (or a near-identical version) from a past exam, including a step-by-step breakdown of the indexing arithmetic (2 * 3 == 6 and 8 - 2 == 6).", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The current snippets rely heavily on the student finding the 'past exam' match. If those weren't there, a student would need a clear guide on negative indexing (e.g., x[-1]) and nested indexing (e.g., x[0][1]).", + "missing_concepts": [ + "Negative indexing in lists", + "Multi-dimensional/nested indexing (accessing elements within tuples inside a list)" + ], + "proposed_fix": "Add a foundational snippet explaining that index -1 is the last item, -2 is second to last, and how x[0][1] traverses the first list item then the second tuple item." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Indexing Cheat Sheet. Content: x[0] is first, x[-1] is last. For x = [(a, b)], x[0][0] is 'a' and x[0][1] is 'b'.", + "why_helpful": "Provides the structural rules to solve the math manually without relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "The 'near identical' exam pieces already provide the answer for this specific problem instance.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:17:21Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q14", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q14", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "Basic loop 2", + "question": "Which of the following code segments will print every even number between 0 and 20 (including 0 and 20) to the screen?", + "options": { + "a": "for i in range(0, 20):\n if i % 2 == 0:\n print(i)", + "b": "i = 0\nwhile i <= 20:\n if i % 2 == 0:\n print(i)\n i += 1", + "c": "for i in list(range(0, 20)):\n print(i if i % 2 == 0 else None)", + "d": "i = 0\nwhile i < 21:\n print(i)\n i += 1" + }, + "correct": "b", + "explanation": "Option B checks every integer from 0 through 20 inclusive and prints only the even ones. Option A never reaches 20, option C also prints None for odd numbers, and option D prints every number.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D)." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D)." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "While the code is not shown, the text confirms that 'sum_even_in_list' involves filtering for even integers, which reinforces the concept of searching for parity-checking logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "This snippet explicitly explains that a while loop with a condition like 'i < 11' runs for values 1 through 10. This helps a student interpret the boundary conditions in the question's while loops (options B and D).", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "While the code is not shown, the text confirms that 'sum_even_in_list' involves filtering for even integers, which reinforces the concept of searching for parity-checking logic.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops" + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "No snippet explains the modulo operator (%) used to check for even numbers (i % 2 == 0). Furthermore, there is no explanation that range(0, 20) is exclusive of 20, which is the primary reason option A is incorrect.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate snippets fail to define the two most critical mechanics for this question: the modulo operator for parity and the upper-bound behavior of the range() function.", + "missing_concepts": [ + "modulo operator (%)", + "range() upper bound exclusivity" + ], + "proposed_fix": "Add a foundational snippet from Week 2 (Loops) or Week 1 (Expressions) explaining that 'a % b' is the remainder and that 'range(start, stop)' stops before 'stop'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Loop and Math Basics' explaining: 1. 'range(0, 10)' produces numbers 0-9 (excludes 10). 2. 'x % 2 == 0' checks if a number is even.", + "why_helpful": "This would allow a student to eliminate distractors A and C (due to range behavior) and confirm B over D (due to even-number filtering).", + "why_maybe_unnecessary": "Basic math might be assumed, but range behavior is specific to Python and essential here.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:17:48Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q15", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q15", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "Basic scope 2", + "question": "Choose the correct statement about the program below:", + "options": { + "a": "a is a global variable. b, c, d are local variables.", + "b": "a, b are global variables. c, d are local variables.", + "c": "a, b, c, d are global variables.", + "d": "a, c, d are global variables. b is a local variable." + }, + "correct": "a", + "explanation": "`a` is defined at module level, so it is global. `b` is local to `outer`, and `c` and `d` are local to `inner`.", + "code_context": "a = 1\ndef outer(b):\n b = 2\n def inner(c):\n d = 3\n return a + c + d\n return inner(4) + b" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "This lecture snippet provides the exact definitions needed: 'Local names' include parameter names and any assignment inside a function, while 'Global names' are defined outside any function. This maps perfectly to 'a' (outside), 'b' and 'c' (parameters), and 'd' (assignment)." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "This lecture snippet provides the exact definitions needed: 'Local names' include parameter names and any assignment inside a function, while 'Global names' are defined outside any function. This maps perfectly to 'a' (outside), 'b' and 'c' (parameters), and 'd' (assignment)." + }, + { + "item_id": "manual-local-name", + "rationale": "Explicitly confirms that parameter names (like 'b' and 'c' in the question) are local to the function body, which reinforces the primary rule." + }, + { + "item_id": "ks-f069ee6a0b", + "rationale": "Explains that functions can be defined inside other functions, which helps a student with no prior knowledge understand the nested 'outer/inner' structure shown in the code." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "manual-local-name", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "This lecture snippet provides the exact definitions needed: 'Local names' include parameter names and any assignment inside a function, while 'Global names' are defined outside any function. This maps perfectly to 'a' (outside), 'b' and 'c' (parameters), and 'd' (assignment).", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:manual-local-name", + "rationale": "Explicitly confirms that parameter names (like 'b' and 'c' in the question) are local to the function body, which reinforces the primary rule.", + "critical_piece_ids": [ + "manual-local-name" + ] + }, + { + "snippet_id": "item:ks-f069ee6a0b", + "rationale": "Explains that functions can be defined inside other functions, which helps a student with no prior knowledge understand the nested 'outer/inner' structure shown in the code.", + "critical_piece_ids": [ + "ks-f069ee6a0b" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:manual-local-name", + "rationale": "", + "needed_piece_ids": [ + "manual-local-name" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The definition in ks-2a6510492d is comprehensive. It allows a student to look at each variable in the code and classify it as global or local based on whether it is outside a function or inside as a parameter/assignment. The supporting snippets clarify the structure and parameters specifically.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Existing snippets cover the classification logic completely.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:18:12Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-extra_practice-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modif" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:ks-00b2983ca8", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "ks-00b2983ca8", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Return statement\nReturns a value to the caller. If you don't capture the return value it's lost. A function leaves no traces — local names are gone after function ends. Common error: using print() instead of return in homework functions.\nReturning a tuple (multiple values)\ndef po" + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:ks-f069ee6a0b", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "ks-f069ee6a0b", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Nested functions and function factories\nFunctions can be defined inside other functions. The inner function is only visible to the outer function. Functions are objects — a function can return another function (factory pattern).\nFunction factory\ndef function_factory(increment):\n " + } + ] + }, + { + "snippet_id": "item:manual-local-name", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "manual-local-name", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Why does `print(n1)` fail outside `def adder(n1, n2): ...`?\nParameter names are local to the function body, so they do not exist in the global scope after the call finishes.\ndef adder(n1, n2):\n return n1 + n2\n\nadder(1, 2)\nprint(n1)" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?\na\nb\nc\nd\nb\nThe global variable 'a' is accessible inside the inner function without error. The code evaluates to inner(5) * 3 = (1 + 5 + 4) * 3 = 30." + } + ] + }, + { + "snippet_id": "item:ks-d26b85265c", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "ks-d26b85265c", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Default arguments\nDefault values are part of the function HEADER (not the call). When argument is omitted, the default is used. Keyword args in a call use =. CRITICAL: mutable defaults are evaluated ONCE at def time — never use mutable defaults; use None instead.\nDefault value\nde" + } + ] + }, + { + "snippet_id": "item:manual-unboundlocal", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "manual-unboundlocal", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Why can assigning to a name inside a function cause `UnboundLocalError`?\nIf a function assigns to a name anywhere in its body, Python treats that name as local throughout the function unless you declare it `global` or `nonlocal`.\nb = 1\n\ndef main(a):\n b = b\n return a" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q16", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q16", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-1", + "question": "You have to write a function called main, which takes a list of unique integers as an argument and returns a dictionary.\n\nThe output dictionary should consist of all key-value pairs for which the key is an element of the input list and the value is the next element of the input list. When there is no \"next element\" any more, leave the key-value pair out of the dictionary.\n\nFor example, if your function is called as:\nmain([1, 3, 2, 4])\nthen it should return the dictionary:\n{1: 3, 3: 2, 2: 4}\n\nWhich of the following programs work(s) according to the requirements?", + "options": { + "a": "def main(l1):\n result = {}\n index = 0\n while True:\n index = index + 1\n if index >= len(l1):\n break\n else:\n result[l1[index]] = l1[index + 1]\n return result", + "b": "def main(l1):\n result = {}\n for index, value in zip(l1[:-1], l1[1:]):\n result[index] = value\n return result", + "c": "Both programs work as required", + "d": "Neither of the two programs works as required" + }, + "correct": "b", + "explanation": "Option B correctly zips each element with the following element and builds the required dictionary. Option A starts at index 1 and eventually tries to access past the end of the list.", + "code_context": "main([1, 3, 2, 4])\n# should return {1: 3, 3: 2, 2: 4}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-5", + "rationale": "The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-5", + "rationale": "The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Shows the pattern of initializing an empty dictionary 'y = {}' and populating it with 'y[key] = value' during a loop, which is central to evaluating Option A and B." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Lists and Sets' piece clarifies dictionary equality, helping a student understand that the key-value pairs define the dictionary identity." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-5", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-5", + "rationale": "The 'Arguments' piece shows a function taking a list and returning a dictionary, which matches the signature of the 'main' function in the question.", + "critical_piece_ids": [ + "aiq-5" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "Shows the pattern of initializing an empty dictionary 'y = {}' and populating it with 'y[key] = value' during a loop, which is central to evaluating Option A and B.", + "critical_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Lists and Sets' piece clarifies dictionary equality, helping a student understand that the key-value pairs define the dictionary identity.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The question relies entirely on understanding list slicing (l1[:-1], l1[1:]) and the zip() function to evaluate Option B. None of the provided snippets explain these concepts. Furthermore, the logic error in Option A (indexing) requires knowledge of 0-based indexing and the behavior of len() in loops, which is not clearly illustrated.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Crucial sequence manipulation concepts (slicing and zipping) are missing.", + "missing_concepts": [ + "List slicing (l1[:-1], l1[1:])", + "The zip() function for pairing elements", + "Off-by-one errors in while-loops with index incrementing" + ], + "proposed_fix": "Add a snippet or piece explaining the 'sliding window' pattern using zip and slicing, and another demonstrating why starting an index at 1 and accessing index+1 leads to errors." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "aiq-5", + "proposal": "Update the 'Higher-Order Patterns' piece to include zip(): 'zip(l1, l2) creates pairs of elements from two sequences. zip(l[:-1], l[1:]) is a common pattern to pair each element with its successor.'", + "why_helpful": "Directly explains the core logic of the correct answer (Option B).", + "why_maybe_unnecessary": "While helpful, it might be better as a standalone 'Sequence Manipulation' snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:18:43Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-extra_practice-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\n\ndef func1(l1):\n return len(list(l1))==len(set(l1))\n\nWhich of the functions below returns the same values as the function above, if we call it in any of the following ways?\n\nfunc1(l1 = [1,2,3])\nfunc1(l1 = [1,2,2])\nfunc1(l1 = (1,2,2))\na\n" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q17", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q17", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-2", + "question": "What will be printed by the following program?", + "options": { + "a": "True", + "b": "False", + "c": "An error message", + "d": "None" + }, + "correct": "a", + "explanation": "Dictionary equality compares key-value contents rather than insertion order. Since both dictionaries contain the same pairs, the comparison prints True.", + "code_context": "d1 = {1: 5, 4: 6}\nd2 = {4: 6, 1: 5}\nprint(d1 == d2)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are." + }, + { + "item_id": "aiq-1", + "rationale": "Contains a reference to a dictionary ('characters') and mentions checking if methods mutate lists in place, providing some context that dictionaries involve keys and values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the `{}` syntax for dictionaries." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "This is the only snippet that explicitly demonstrates dictionary syntax `{key: value}`. While it focuses on `.values()` and `.keys()`, it shows the structure of a dictionary which is essential for a student with zero knowledge to identify what `d1` and `d2` are.", + "critical_piece_ids": [ + "exam-trial_midterm-10-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-1", + "rationale": "Contains a reference to a dictionary ('characters') and mentions checking if methods mutate lists in place, providing some context that dictionaries involve keys and values.", + "critical_piece_ids": [ + "aiq-1" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "rationale": "Shows the `{}` syntax for dictionaries.", + "needed_piece_ids": [ + "exam-trial_midterm-10-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain that dictionary equality (`==`) in Python compares the content (key-value pairs) regardless of the order in which they were defined. A student with zero knowledge would likely guess based on the numbers being the same, but wouldn't know for certain if order matters in Python collections.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets identify dictionaries but fail to explain the 'unordered' nature of standard dictionary comparison.", + "missing_concepts": [ + "dictionary equality comparison", + "order-insensitivity of dictionary contents for ==" + ], + "proposed_fix": "Add a snippet or AI question that specifically addresses how Python compares dictionaries vs lists (where order does matter)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new AI piece: 'Dictionary Equality: Two dictionaries are considered equal (==) if they have the same key-value pairs, regardless of the order in which the pairs were added. Example: {1: 'a', 2: 'b'} == {2: 'b', 1: 'a'} is True.'", + "why_helpful": "It directly addresses the core logic of the exam question which tests content-based comparison vs order-based comparison.", + "why_maybe_unnecessary": "If the student assumes Python behaves 'intuitively' regarding sets of data, they might guess correctly, but it's a specific language rule.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:18:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-24-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-24-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA The code will result in an error.\nB True\nC None\nD False\nEnd of test Trial Midterm - Introduction to Pyth" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "str.upper() / string methods don't modify in place\ns.upper() returns a new string; s is unchanged. Must do s = s.upper()" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:aiq-1", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Condition flow and branch result\nExam • midterm_2024 • Q1\nConsider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have a dictionary called characters, of which keys are strings and values are lists of strings.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • trial_midterm • Q2" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Which of the following statements is correct? I: Two objects can have different values, while having the same type. II: Two objects can have the same value, while having different types.\nI is correct (e.g. a=1, b=2, both int). II is incorrect — if two objects have the same value " + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Operators and Truth", + "subtopic_title": "", + "search_text": "What is the result of (a//b)*b + a%b?\nArithmetic operators" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Mutable default argument\nCheck whether the method mutates the list in place and what the list looks like after each call.\nMutable default argument" + }, + { + "item_id": "aiq-1", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You have four different blocks of code. Three of them return the same list, one of them returns something different.\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • trial_midterm • Q17\nA def square" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q18", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q18", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "final-dictionary-3", + "question": "d1 = {1: 2, 2: 1}\n\nThe following code segments all print exactly the same output, except for one. Which one?", + "options": { + "a": "result = 1\nfor x in d1.values():\n result *= x\nprint(result)", + "b": "result = -1\nfor x in d1.keys():\n result += d1[x]\nprint(result)", + "c": "result = 4\nfor x in d1.items():\n result = result // x[1]\nprint(result)", + "d": "result = -4\nfor x in d1:\n result /= d1[x]\nprint(result)" + }, + "correct": "d", + "explanation": "A, B, and C all print 2. Option D uses true division starting from -4, so it prints -2.0 instead, making it the odd one out.", + "code_context": "d1 = {1: 2, 2: 1}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Provides a basic example of dictionary structure and calculation, though it lacks the specific methods (.values, .items) needed for this question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "It explicitly clarifies that iterating directly over a dictionary yields only keys, which is the key mechanism for Option D.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "Provides a basic example of dictionary structure and calculation, though it lacks the specific methods (.values, .items) needed for this question.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The snippets do not define '.values()', '.keys()', or '.items()', nor do they explain that '.items()' yields tuples where indexing (x[1]) is required. Crucially, there is no explanation of the difference between true division (/) and floor division (//), which is the primary reason Option D is the odd one out (producing a float).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing definitions for dictionary iteration methods and the semantic difference between division operators.", + "missing_concepts": [ + "dict.values()", + "dict.keys()", + "dict.items()", + "Tuple indexing in loops (x[1])", + "True division (/) vs Floor division (//)" + ], + "proposed_fix": "Add a reference item covering dictionary iteration methods and a section on arithmetic operators highlighting float vs int outputs." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Dictionary Iteration & Division' that shows: 1) 'for x in d.values()' yields values. 2) 'for x in d.items()' yields (key, value) pairs, accessible via x[1]. 3) '/' always returns a float (e.g., 4 / 2 = 2.0) while '//' returns an integer (4 // 2 = 2).", + "why_helpful": "This allows a zero-knowledge student to map the code options to their results and identify why Option D (using /) produces a different type/value than the others.", + "why_maybe_unnecessary": "No reason to skip; this is a common 'trick' question type in the exam.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:19:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-21-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "The following codes all print the same value, except one. Which one?\nA\nB\nC\nD\nA\nIterating directly over a dictionary (for key, value in d1) only yields keys. This will cause a ValueError when trying to unpack into two variables." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q19", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q19", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-1", + "question": "Suppose that you have a string called s1, which contains several letters. The letter \"x\" and the letter \"y\" occur exactly once in the string, and \"x\" always precedes \"y\".\n\nYou'd like to print out a string that looks just like s1, except that the letters \"x\" and \"y\" should be swapped.\n\nFor example, if:\ns1 = \"axbyc\"\nthen you'd like to print:\naybxc\n\nReminder: The replace string method has a third argument, which allows you to specify the maximum number of replacements you want to make, counting from left to right.", + "options": { + "a": "s1 = s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "b": "s1 = s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)", + "c": "s1.replace('x', 'y', 1).replace('y', 'x', 1)\nprint(s1)", + "d": "s1.replace('y', 'x', 1).replace('x', 'y', 1)\nprint(s1)" + }, + "correct": "b", + "explanation": "Option B first changes the single y to x, then changes the first x from left to right back to y, which swaps the two letters. Options C and D do not assign the new string back to s1, and A changes the first replacement back incorrectly.", + "code_context": "s1 = \"axbyc\"\n# desired printed result: aybxc" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions return values (or None) and needs to be captured, which is helpful for understanding why Options C and D (which lack assignment) are incorrect." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-2", + "rationale": "This is the only snippet family that explicitly categorizes 'String Operations and Methods'. While the current content focuses on slicing, it is the most logical home for string-related logic.", + "critical_piece_ids": [ + "aiq-2" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions return values (or None) and needs to be captured, which is helpful for understanding why Options C and D (which lack assignment) are incorrect.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the snippets explain string immutability (the fact that .replace() returns a NEW string and does not modify the original). Without this knowledge, a student cannot distinguish between Options A/B and C/D. Additionally, there is no explanation of the left-to-right execution of chained .replace() calls, which is necessary to understand why B is correct and A is not.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The provided snippets focus on slicing, lists, and OOP, completely missing string method mechanics and the concept of immutability.", + "missing_concepts": [ + "String Immutability (methods return new strings; they don't mutate in place)", + "str.replace() behavior and argument order", + "Method Chaining execution order (left-to-right)" + ], + "proposed_fix": "Add a snippet specifically for 'String Immutability' and 'The .replace() method' showing that s.replace() requires s = s.replace() to save changes." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: String Immutability and .replace()\nContent:\nStrings are IMMUTABLE. Methods like .replace() do NOT change the original string; they return a NEW string.\nCorrect: s = s.replace('a', 'b')\nIncorrect: s.replace('a', 'b') (original 's' remains unchanged)\n\nChained methods: s.replace('x', 'y').replace('y', 'z')\nPython executes from left to right. The second .replace() sees the result of the first one.", + "why_helpful": "This directly addresses the two main pitfalls of the question: the need for reassignment (assignment back to s1) and the sequential logic of swapping characters.", + "why_maybe_unnecessary": "The question contains a 'Reminder' about the 3rd argument, but it does not remind the student about immutability or execution order.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:19:44Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "Slicing negative step\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.\nSlicing negative step" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q20", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q20", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-2", + "question": "Take a look at the following function definition.\n\nWhat will be returned by the following function call:\nglue(a='e', b='d')", + "options": { + "a": "ab", + "b": "cd", + "c": "ba", + "d": "dc" + }, + "correct": "c", + "explanation": "The function iterates over the keyword names in insertion order (`a`, then `b`) and prepends each key to the current result. Starting from the empty string, that produces `a`, then `ba`.", + "code_context": "def glue(**kwargs):\n result = ''\n for el in kwargs.keys():\n result = el + result\n return result" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents." + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "Demonstrates the syntax for iterating over keys in a dictionary-like structure (for key in x), which is essential for tracing the 'for el in kwargs.keys()' loop." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-18-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Defines the concept of a 'flexible number of keyword arguments' and provides an example function call that mirrors the structure of the question, helping a student understand what **kwargs represents.", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "Demonstrates the syntax for iterating over keys in a dictionary-like structure (for key in x), which is essential for tracing the 'for el in kwargs.keys()' loop.", + "critical_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-18-w2-loops" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain that **kwargs handles multiple keyword arguments and show how loops iterate over keys. However, they do not explicitly state that the 'keys' in **kwargs are the argument names (the strings 'a' and 'b') or that Python preserves the insertion order of these arguments, which is critical to deciding between 'ab' and 'ba'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "There is no explicit explanation that **kwargs keys map to the argument names and follow the order of the function call.", + "missing_concepts": [ + "**kwargs dictionary mapping (parameter names as keys)", + "Keyword argument insertion order preservation", + "Behavior of .keys() on a **kwargs object" + ], + "proposed_fix": "Add a snippet clarifying that **kwargs collects parameters into a dictionary where the names (the left side of the '=') are keys, and that they are processed in the order they appear in the call." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Concept: Keyword Arguments (**kwargs). In a function definition like def f(**kwargs), 'kwargs' is a dictionary. If you call f(x=1, y=2), the keys are the strings 'x' and 'y', and the values are 1 and 2. Python remembers the order: 'x' comes before 'y' in loops.", + "why_helpful": "This directly bridges the gap between the function call and the loop behavior in the question.", + "why_maybe_unnecessary": "A student might guess that 'a' and 'b' are the keys, but knowing they are strings and follow order is specific technical knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:20:19Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q21", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q21", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "final-functions-3", + "question": "Take a look at the following function definition.\n\nWhat will be printed to the screen by the following code?\nprint(tester())", + "options": { + "a": "1", + "b": "-1", + "c": "0", + "d": "None" + }, + "correct": "a", + "explanation": "The default argument is `0`, which satisfies the non-negative condition, so the function returns `1` and `print` outputs `1`.", + "code_context": "def tester(i1 = 0):\n if i1 >= 0:\n return 1\n\n if i1 < 0:\n return -1" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly shows a function definition with multiple default arguments (num2=10, num3=20) and demonstrates how the function behaves when some arguments are omitted in the call, which is the core concept needed to solve the tester() question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly shows a function definition with multiple default arguments (num2=10, num3=20) and demonstrates how the function behaves when some arguments are omitted in the call, which is the core concept needed to solve the tester() question." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Explains that print() is a built-in function that outputs its argument to the screen, helping the student understand the final step of the code execution." + }, + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "rationale": "Reinforces the concept of default arguments by stating 'y defaults to 11' in its explanation of a function call." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "This snippet explicitly shows a function definition with multiple default arguments (num2=10, num3=20) and demonstrates how the function behaves when some arguments are omitted in the call, which is the core concept needed to solve the tester() question.", + "critical_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Explains that print() is a built-in function that outputs its argument to the screen, helping the student understand the final step of the code execution.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "rationale": "Reinforces the concept of default arguments by stating 'y defaults to 11' in its explanation of a function call.", + "critical_piece_ids": [ + "exam-Resit 22/23-4-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate snippets effectively explain the two potential hurdles: how default arguments work when a function is called without them, and what the print function does with the return value.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover default arguments and the print function well. There is no explicit breakdown of comparison operators like '>=' but they are intuitive enough for a general student.", + "missing_concepts": [ + "explicit explanation of comparison operators (>=, <)" + ], + "proposed_fix": "Add a small knowledge snippet defining common comparison operators (>, <, >=, <=, ==, !=)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A lecture-style snippet explaining default parameter values: 'When you define a function like def f(x=0), if you call f() without any arguments, Python automatically sets x to 0.'", + "why_helpful": "This would be the most direct 'rule' for a student to apply to this specific question.", + "why_maybe_unnecessary": "Existing exam snippets show this behavior through examples, which might be sufficient for pattern recognition.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:20:41Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
                      • A function is a grouping of code that can perform a certain task and can be re-used \n
                      • Print is a built-in function, tha" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q22", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q22", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "List lambda 2", + "question": "Assume that you have a variable called x, which contains a list of integers.\n\nWhich of the following code segments will create another list that has every element of x multiplied by 2?\n\nFor example, if\nx = [1, 2, 3, 4, 5]\nthen which of the following code segments will result in the list:\n[2, 4, 6, 8, 10]", + "options": { + "a": "list(map(lambda i : i * 2, x))", + "b": "[(lambda i : i * 2)(item) for item in x]", + "c": "y = lambda i : i * 2\n[y(i) for i in x]", + "d": "All three code segments would work as intended" + }, + "correct": "d", + "explanation": "Each option constructs the doubled list correctly: `map` with a lambda, an immediately called lambda inside a list comprehension, and a named lambda used inside a list comprehension all apply `i * 2` to every element of `x`.", + "code_context": "x = [1, 2, 3, 4, 5]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a)." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a)." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates the 'list()' constructor being used to wrap an iterable, which helps explain the structure of the code in option (a)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This is the only snippet that mentions a '.map()' method and explains the concept of applying a function to elements in a collection, which is relevant to understanding option (a).", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Demonstrates the 'list()' constructor being used to wrap an iterable, which helps explain the structure of the code in option (a).", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The candidate snippets completely lack an explanation of 'lambda' (anonymous functions) and 'list comprehensions', which are the two most critical concepts required to evaluate the code segments in this question.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a complete absence of documentation for functional programming primitives (lambda, map) and Pythonic iteration (list comprehensions) in the provided candidates.", + "missing_concepts": [ + "lambda syntax (lambda arguments : expression)", + "built-in Python map() function", + "list comprehension syntax [expr for item in iterable]", + "immediately called lambda expressions" + ], + "proposed_fix": "Add a 'Functional Programming and Comprehensions' snippet that covers lambda definitions, the built-in map() function, and the transformation pattern in list comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Anonymous Functions (Lambda) and Iteration Tools' explaining: 1. Lambda syntax. 2. How the built-in map() function applies a function to a list. 3. Basic list comprehension syntax for transforming data.", + "why_helpful": "This question tests if the student recognizes that a lambda can be passed to map, called immediately inside a comprehension, or assigned to a variable and then called. None of these behaviors are covered by existing snippets.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:21:10Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q23", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q23", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "List logic 2", + "question": "Which of the following programs creates a new list y, in which the elements are those elements of list x that are equal to their indices?\nYou can assume x consists of unique integers.\n\nFor example, if:\nx = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\nthen the program should create a new list y such that:\ny = [0, 3, 6, 7, 8, 10]", + "options": { + "a": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(i)", + "b": "y = []\nfor i, j in enumerate(x):\n if i == j:\n y.append(j)", + "c": "y = [i for i in x if i == x.index(i)]", + "d": "All three programs would work as intended" + }, + "correct": "d", + "explanation": "In A and B, whenever `i == j`, appending either `i` or `j` gives the same value because the index equals the element. In C, `x.index(i)` returns the position of `i`, so the comprehension keeps exactly the elements equal to their indices. Therefore all three programs work.", + "code_context": "x = [0, 2, 4, 3, 5, 9, 6, 7, 8, 1, 10]\n# target result:\ny = [0, 3, 6, 7, 8, 10]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Although it uses Pandas, it discusses using a 'boolean mask on the index' to select specific elements, which introduces the student to the concept of index-based selection logic." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes a transformation where elements are compared to a 'mean of the elements', reinforcing the pattern of evaluating list/series values against a common property." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "This snippet is the only one that explicitly mentions 'filtering' a list based on a condition (even integers/non-integers), which is conceptually the closest match to filtering based on index-value equality.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Although it uses Pandas, it discusses using a 'boolean mask on the index' to select specific elements, which introduces the student to the concept of index-based selection logic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Describes a transformation where elements are compared to a 'mean of the elements', reinforcing the pattern of evaluating list/series values against a common property.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "None of the provided snippets explain 'enumerate()', list comprehensions for filtering, or the 'list.index()' method. Without knowing how 'enumerate' unpacks into an index and a value, a student with zero prior knowledge cannot distinguish between options A, B, and C.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is a total lack of foundational list manipulation and iteration utilities in the candidate pool.", + "missing_concepts": [ + "enumerate() usage for index/value pairs", + "List comprehension syntax for filtering", + "list.index(item) method behavior" + ], + "proposed_fix": "Create a new snippet specifically covering 'List Iteration and Filtering' that demonstrates enumerate and basic comprehensions." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Snippet: List Filtering and Indexing. Content: 1. `enumerate(x)` allows you to loop through a list and get both the position (index) and the item: `for i, item in enumerate(x):`. 2. List comprehensions filter data: `[item for item in x if condition]`. 3. `x.index(val)` finds where `val` first appears in list `x`.", + "why_helpful": "This directly maps to all three logical implementations (A, B, and C) shown in the question, enabling the student to see why they are equivalent.", + "why_maybe_unnecessary": "It is a basic concept, but crucial for 'List Logic' questions which are frequent in the syllabus.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:21:39Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-solutions-for-python-programming-62oop21-q24", + "question_id": "final-exam-solutions-for-python-programming-62oop21-q24", + "exam_id": "final-exam-solutions-for-python-programming-62oop21", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "List loop 2", + "question": "Assume that you have a list called x, which is a list of multiple sub-lists containing integers.\n\nWhich of the following programs will create a new list y that is equal to the sub-list of x whose sum of elements is the highest?\n\nYou can assume that the sum of elements in each sub-list is a different number, so that there is only one that is the highest.\n\nFor example, if:\nx = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\nthen y should be:\ny = [8, 20, 300]", + "options": { + "a": "y = max(x)", + "b": "z = []\nfor i in x:\n z.append(sum(i))\ny = x[z.index(max(z))]", + "c": "x.sort()\ny = x[-1]", + "d": "y = [i for i in x if sum(i) == max(x)]" + }, + "correct": "b", + "explanation": "Option B computes the sum of each sub-list, finds the position of the largest sum, and then returns the corresponding original sub-list. The other options compare lists lexicographically or compare a numeric sum against `max(x)`, which is a list.", + "code_context": "x = [[8, 20, 300], [7, 8, 9], [10, 11, 12], [40, 5, 6]]\n# target result:\ny = [8, 20, 300]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items." + }, + { + "item_id": "aiq-2", + "rationale": "Includes examples of list methods like .append(), which is used in the correct answer's loop to build the helper list." + }, + { + "item_id": "aiq-4", + "rationale": "Provides a hint about list properties and equality (e.g., [1,2]==[2,1] is False), though it lacks specific lexicographical comparison details." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "aiq-2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates a pattern structurally identical to the correct option: iterating over a list, performing a computation on each element (lengths vs. sums), and storing results to associate them with the original items.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "Includes examples of list methods like .append(), which is used in the correct answer's loop to build the helper list.", + "critical_piece_ids": [ + "aiq-2" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Provides a hint about list properties and equality (e.g., [1,2]==[2,1] is False), though it lacks specific lexicographical comparison details.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets fail to define the 'sum()' function, the 'max()' function, and the 'list.index()' method, all of which are essential to understanding the correct option (B). Furthermore, there is no explanation of lexicographical comparison, which is necessary to understand why 'max(x)' in options A and D compares the first elements of the sub-lists rather than their sums.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The student lacks definitions for the core built-in functions (sum, max) and list methods (index) used in the logic, as well as the concept of list-of-lists comparison behavior.", + "missing_concepts": [ + "sum() function on lists", + "max() function on lists of integers", + "list.index() method", + "Lexicographical comparison of lists (how max() works on a list of lists)" + ], + "proposed_fix": "Add a snippet explicitly covering 'Aggregations and Search' that defines sum(), max(), and .index(), and another piece clarifying that max([[100], [200, 1]]) compares the first elements (100 vs 200) rather than the total count or sum." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: List Aggregations. Content: Explain sum(mylist) returns the total of elements; max(mylist) returns the largest element; mylist.index(x) returns the position of x. Add a warning that max() on a list of lists compares them element-by-element (e.g., [2, 1] > [1, 100]).", + "why_helpful": "This directly enables the student to parse the logic in Option B and realize why Option A is incorrect.", + "why_maybe_unnecessary": "If the student already understands these standard Python functions from basic lecture notes, but the goal is zero prior knowledge support.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:22:05Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-study-guide-trial-python-basics-2023.json b/data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-study-guide-trial-python-basics-2023.json new file mode 100644 index 0000000..a7a4a37 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round2/final-exam-study-guide-trial-python-basics-2023.json @@ -0,0 +1,8848 @@ +{ + "schema_version": "1.1", + "generated_at": "2026-03-24T10:43:09Z", + "round": "round2", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q01", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q01", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_2", + "question": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\n- If they travel within Europe, your program should print \"No passport needed. Bring your ID card.\"\n- If they travel outside of Europe, the program should print \"Please bring your passport.\"\n\nWhich of the following code segment will achieve what you need?", + "options": { + "a": "if destination in europe:\n print('No passport needed. Bring your ID card.')\nelse:\n print('Please bring your passport.')", + "b": "if destination in europe:\n return 'No passport needed. Bring your ID card.'\nelif destination not in europe:\n return 'Please bring your passport.'", + "c": "for country in europe:\n if destination = country:\n print('No passport needed. Bring your ID card.')\n else:\n print('Please bring your passport.')", + "d": "for country in europe:\n if destination != country:\n return 'Please bring your passport.'\n else:\n return 'No passport needed. Bring your ID card.'" + }, + "correct": "a", + "explanation": "Option A directly checks whether destination is in the list of European countries and prints the correct message in each case. The other options either use the wrong control flow or invalid syntax.", + "code_context": "europe = [...]\ndestination = ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows a list-based scenario where the goal is to print formatted strings, reinforcing the use of print() over return." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "rationale": "This piece contains the exact text and logic of the current question, providing the answer directly." + } + ], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "This snippet explains return behavior (return vs print), which is crucial for identifying that options (b) and (d) are incorrect in a script context. It also covers list and set equality, though less directly relevant here.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows a list-based scenario where the goal is to print formatted strings, reinforcing the use of print() over return.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the identical past exam piece, there is no snippet provided that explains the 'in' operator for membership testing or the basic 'if-else' control flow syntax. While 'aiq-4' helps eliminate 'return' options, the student cannot distinguish between the correct 'in' check and the logically flawed 'for' loop in option (c).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to explain membership operators and basic conditional logic outside of a function context.", + "missing_concepts": [ + "Membership operators (in, not in)", + "Basic if-else syntax", + "Comparison (==) vs Assignment (=)" + ], + "proposed_fix": "Add a foundational snippet covering membership testing in lists/strings and basic if-else blocks that use print statements." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Membership and Logic' explaining: 1. Using 'in' to check if a value exists in a list. 2. The difference between 'if-else' (two branches) and 'for' loops (iterating over every item). 3. Printing versus returning in global script scope.", + "why_helpful": "It would directly address the 'in' operator used in the correct answer and help students avoid the 'for loop' trap in Option C.", + "why_maybe_unnecessary": "Basic logic is often considered prerequisite, but for 'zero knowledge' goals, it is essential.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:22:32Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-10-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-extra_practice-10-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function main(target_num, list_num) that returns all unique pairs of numbers that add up to target_num.\n\nExample: main(11, [4,5,6,9,3,7,2,8]) should return [(5,6),(4,7),(9,2),(3,8)].\n\nNote: (6,5) is not included since (5,6) is already found.\n\nWhich of the foll" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q02", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q02", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_3", + "question": "Calling the function func_10 will produce an error. Which line of the following code segment produces the error?", + "options": { + "a": "'var_2 = var_1 * var'\nThis line produces the error because func_2() was not called and assigning the value to var_1, thus var_1 was referenced before being defined.", + "b": "'var_1 = var * 2'\nThis line produces the error because Python is confused about which value var should have.", + "c": "'def func_2(var):'\nThis line produces the error because the name var is already used for the argument of func_1() and cannot be used again as the name of the argument for func_2().", + "d": "'return var_2'\nThis line produces the error because one function cannot return two outputs." + }, + "correct": "a", + "explanation": "The inner function func_2 is defined but never called, so var_1 is never assigned before the line var_2 = var_1 * var tries to use it.", + "code_context": "def func_1(var):\n def func_2(var):\n var_1 = var * 2\n return var_1\n var_2 = var_1 * var\n return var_2" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Directly explains the core concept of local scope: names defined inside a function are local and only known within that function. This allows a student to conclude that var_1, defined inside func_2, cannot be accessed by func_1." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Directly explains the core concept of local scope: names defined inside a function are local and only known within that function. This allows a student to conclude that var_1, defined inside func_2, cannot be accessed by func_1." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Defines what a function is (a grouping of code), which helps a student with zero prior knowledge understand the structure of the nested 'def' blocks in the code segment." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "rationale": "This piece describes an almost identical scenario with the same logic: an inner function (func_2) is defined but never called, making its local variables (var_1) inaccessible to the outer function (func_1)." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "Directly explains the core concept of local scope: names defined inside a function are local and only known within that function. This allows a student to conclude that var_1, defined inside func_2, cannot be accessed by func_1.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Defines what a function is (a grouping of code), which helps a student with zero prior knowledge understand the structure of the nested 'def' blocks in the code segment.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of defining what a function is and explaining that local variables are only known inside their function provides all the logical components needed to identify the scope error described in the correct option.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets are sufficient for the intended logic. There is a minor typo in the question text (func_10 vs func_1), but the options and code context make the intended question clear.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:23:06Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
                        • A function is a grouping of code that can perform a certain task and can be re-used \n
                        • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q03", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q03", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[str, int, NoneType, bool, float, str, dict]", + "b": "[str, int, NoneType, bool, float, bool, dict]", + "c": "[str, int, NoneType, bool, float, str, list]", + "d": "[str, float, NoneType, bool, int, str, dict]" + }, + "correct": "a", + "explanation": "The function appends the type of each element in the input list in order: string, integer, NoneType, boolean, float, string, and dictionary.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n list_2.append(type(item))\n return list_2\n\nmain(['abc', 0, None, True, 123.456, 'False', {}])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-cb3a9e3fd2", + "rationale": "Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner." + }, + "top_three_snippets": [ + { + "item_id": "ks-cb3a9e3fd2", + "rationale": "Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner." + }, + { + "item_id": "ks-eae9bf47dd", + "rationale": "Confirms that 'dict' is one of the standard Python types, which is necessary to identify the {} element." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-cb3a9e3fd2", + "rationale": "" + }, + { + "item_id": "ks-eae9bf47dd", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This piece contains the exact same code elements ('abc', 0, None, True, 123.456, 'False', {}) and explicitly maps them to their types, including the 'None' to 'NoneType' mapping and the 'False' in quotes as 'str' distinction." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-cb3a9e3fd2", + "rationale": "Provides the most comprehensive mapping of literal values (integers, floats, strings, booleans) to their respective Python type names (int, float, str, bool) for a beginner.", + "critical_piece_ids": [ + "ks-cb3a9e3fd2" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-eae9bf47dd", + "rationale": "Confirms that 'dict' is one of the standard Python types, which is necessary to identify the {} element.", + "critical_piece_ids": [ + "ks-eae9bf47dd" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-cb3a9e3fd2", + "rationale": "", + "needed_piece_ids": [ + "ks-cb3a9e3fd2" + ] + }, + { + "snippet_id": "item:ks-eae9bf47dd", + "rationale": "", + "needed_piece_ids": [ + "ks-eae9bf47dd" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "high", + "rationale": "The general snippets cover str, int, bool, float, and dict. However, 'NoneType' is missing from all lecture snippets, and the 'type()' function is not explicitly defined outside of exam context explanations. The 'False' string vs. boolean distinction is also only explicitly clarified in the near-identical exam piece.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Lecture snippets define the names of types but lack examples for 'None/NoneType' and do not explicitly define the 'type()' function.", + "missing_concepts": [ + "NoneType", + "type() function behavior" + ], + "proposed_fix": "Add 'None' to the '8 types to know' lecture snippet and include a small section explaining that 'type(x)' returns the type name of object x." + }, + "suggested_changes": [ + { + "kind": "edit_existing", + "target_item_id": "ks-cb3a9e3fd2", + "proposal": "Add 'var_9 = None # NoneType' to the example list and include a note: 'type() returns these type names (e.g., type(123) is int)'.", + "why_helpful": "Allows students to answer questions involving None and type() without relying on having seen the exact exam question before.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:23:32Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:ks-d9760d8cd8", + "snippet_label": "Conversion and Truthiness", + "week": 2, + "topic": "Conversion and Truthiness", + "pieces": [ + { + "item_id": "ks-d9760d8cd8", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Conversion and Truthiness", + "subtopic_title": "", + "search_text": "Type conversion (explicit)\nPython requires explicit conversion in most cases (unlike JavaScript). Conversion functions: str(), int(), float(), bool(), tuple(), list(), set(), dict().\nExplicit conversions\nprint(str(1) == '1') # True\nprint(int('1') == 1) # True\n" + } + ] + }, + { + "snippet_id": "item:ks-eae9bf47dd", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "ks-eae9bf47dd", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Mutable vs immutable types\nImmutable: int, float, str, bool, tuple. Mutable: list, dict, set. The value of a mutable object CAN be changed in-place. The value of an immutable object CANNOT be changed — a new object must be created.\nList is mutable — can change element in place\nl1" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:ks-cb3a9e3fd2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "ks-cb3a9e3fd2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Object types — the 8 types to know\nint, float, str, bool, tuple, list, dict, set\nAll 8 types\nvar_1 = 123 # int\nvar_2 = 123.3 # float\nvar_3 = '123' # str\nvar_4 = True # bool\nvar_5 = ('123', 123) # tuple\nvar_6 = [123, '123'] # " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q04", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q04", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 1", + "question": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\n\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique numerical values to characters.\n\nThat is, if we execute the following command:\nprint(vowels_ASCII)\n\nthe output should be:\n{'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}\n\nWhich of the code segments work(s) as intended?\n\nHint: the ord() function returns a unique numerical value to a character. The function takes a unit-length text as an argument and returns the assigned unique numerical value.\n\nFor example:\nord('a')\n\nreturns:\n97", + "options": { + "a": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou'}", + "b": "vowels_ASCII = {vowel: ord(vowel) for vowel in 'aeiou' if vowel in 'aeiou'}", + "c": "Both of the code segments work correctly.", + "d": "Neither of the code segments work correctly." + }, + "correct": "c", + "explanation": "Both comprehensions produce the same dictionary because the extra condition in option B is always true for characters drawn from 'aeiou'.", + "code_context": "print(vowels_ASCII)\n# expected: {'a': 97, 'e': 101, 'i': 105, 'o': 111, 'u': 117}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates dictionary creation with an 'if' filtering clause, which is relevant to evaluating Option B." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "This piece contains the exact same question prompt about creating the 'vowels_ASCII' dictionary." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the general pattern of using dictionary comprehension to map keys to values (word to word length) and asks which code segments work, mirroring the current question's structure.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Demonstrates dictionary creation with an 'if' filtering clause, which is relevant to evaluating Option B.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the identical question prompt is found, the snippets themselves are truncated and do not show the full code solutions or explanations for the 'ord()' function and dictionary comprehension syntax. A student with zero knowledge would see the pattern but lack the specific function definitions.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets provide examples of the desired output and similar problems, but lack the foundational syntax for dictionary comprehensions and the definition of the 'ord()' function.", + "missing_concepts": [ + "Dictionary comprehension syntax {k: v for x in iterable}", + "ord() function purpose and usage", + "Effect of redundant 'if' conditions in comprehensions" + ], + "proposed_fix": "Add a conceptual snippet from Week 2 lecture materials that explains dictionary comprehensions and common built-in functions like ord()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Dictionary Comprehensions' snippet from Week 2 materials showing the syntax: `{key_expr: value_expr for item in iterable if condition}`.", + "why_helpful": "It would allow the student to understand how Option A and Option B are constructed and why the redundant 'if' in B doesn't invalidate the result.", + "why_maybe_unnecessary": "The 'hint' in the question itself explains ord(), so a separate snippet for that might be overkill if the syntax is understood.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:23:54Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q05", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q05", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 1", + "question": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\n\nYou want to create a dictionary called match_goals where the keys are the match numbers (starting from 1) and the values are a tuple containing the total goals scored by each player in that match.\n\nSo, if we execute the following command:\nprint(match_goals)\n\nthe output should be:\n{1: (2, 0, 1), 2: (1, 1, 0), 3: (3, 1, 2), 4: (2, 3, 1), 5: (1, 2, 3)}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = (goals1, goals2, goals3)", + "b": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals), start=1):\n match_goals[i] = [goals1 + goals2 + goals3]", + "c": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = [goals1, goals2, goals3]", + "d": "match_goals = {}\nfor i, (goals1, goals2, goals3) in enumerate(zip(player1_goals, player2_goals, player3_goals)):\n match_goals[i] = (goals1, goals2, goals3)" + }, + "correct": "a", + "explanation": "Option A uses enumerate with start=1 to create the correct match-number keys and stores each triple of goal counts as a tuple. The other options either use the wrong value shape or start indexing from 0.", + "code_context": "player1_goals = [2, 1, 3, 2, 1]\nplayer2_goals = [0, 1, 1, 3, 2]\nplayer3_goals = [1, 0, 2, 1, 3]\nprint(match_goals)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a conceptual parallel for creating a dictionary from two separate lists (names and ages), which helps a student understand the 'key: value' mapping logic required here." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a conceptual parallel for creating a dictionary from two separate lists (names and ages), which helps a student understand the 'key: value' mapping logic required here." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary ('roman_nums') where keys are integers 1 to 5, which helps validate that the match numbers in the question should be the keys, not the values." + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the task of creating a dictionary from a list of items, reinforcing the pattern of iterating to populate a new dictionary." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "This is the exact same question, including the specific player names, goal lists, and desired dictionary output." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Provides a conceptual parallel for creating a dictionary from two separate lists (names and ages), which helps a student understand the 'key: value' mapping logic required here.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary ('roman_nums') where keys are integers 1 to 5, which helps validate that the match numbers in the question should be the keys, not the values.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Demonstrates the task of creating a dictionary from a list of items, reinforcing the pattern of iterating to populate a new dictionary.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam question is present in the database, making the answer directly findable. However, without the identical piece, the other snippets only describe problems and do not provide the specific syntax for 'enumerate(start=1)' or 'zip'.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While there are many 'create a dictionary' exam prompts, none of the general snippets (excluding the identical one) explicitly show the syntax for 'zip()' or 'enumerate(..., start=1)'.", + "missing_concepts": [ + "syntax for enumerate(iterable, start=1)", + "syntax for zip(list1, list2, list3)", + "distinction between tuple assignment (a, b) and list assignment [a, b] in dictionaries" + ], + "proposed_fix": "Add a reference snippet showing common 'Dictionary Construction Patterns' that explicitly includes examples of zip and enumerate." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "A snippet titled 'Dictionary Population from Lists' demonstrating: 1. zip() to combine lists into values. 2. enumerate(..., start=1) to create sequential keys.", + "why_helpful": "It teaches the underlying mechanics so a student can solve variations of this problem (e.g., if match numbers started at 0 or if the lists were nested).", + "why_maybe_unnecessary": "The current question bank already contains the exact problem, which acts as its own reference.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:24:25Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\ncloset = {\n\"shirts\" : 5,\n\"colors\" : ['red', 'yellow', 'blue', 'pink']\n}\nYou want to:\n- add a key \"shoes\" which has a value that is a list containing the strings \"sneakers\" and \"heels\"\n- add 2 shirts, so that the value of the key \"shirts\"" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q06", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q06", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 1", + "question": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and March). Which of the following code segments works as intended?", + "options": { + "a": "sales_subset = [monthly_sales[key] for key in list(monthly_sales.keys())[:3]]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "b": "sales_subset = monthly_sales[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "c": "sales_subset = list(monthly_sales.items())[:3]\naverage_sales = sum(sales_subset) / len(sales_subset)\nprint(average_sales)", + "d": "sales_subset = monthly_sales['January':'March']\naverage_sales = sum(sales_subset.values()) / len(sales_subset)\nprint(average_sales)" + }, + "correct": "a", + "explanation": "Option A first collects the values for the first three keys into a list and then computes the average correctly. The other options attempt unsupported dictionary slicing or try to sum tuples instead of numeric values.", + "code_context": "monthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question." + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "Shows the concept of summing values from a set of keyword arguments (which act like a dictionary)." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "This is the exact same question as the one being evaluated, providing the correct answer directly." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "While it does not cover slicing, it demonstrates working with a dictionary of names and numeric values, which is the basic structure of the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "Shows the concept of summing values from a set of keyword arguments (which act like a dictionary).", + "critical_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-6-w3-arguments" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the identical past exam piece, none of the snippets explain that dictionaries are unsliceable or how to correctly use list(d.keys())[:3] to get a subset of values. A student wouldn't know why options B, C, or D fail.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to address the core concept of the question: dictionary slicing limitations and the workaround using list conversion of keys.", + "missing_concepts": [ + "dictionaries do not support slicing (dict[:n])", + "slicing list(dict.keys()) to extract specific entries", + "dictionary .items() returns tuples, which cannot be summed directly" + ], + "proposed_fix": "Add a summary snippet or lecture piece explicitly stating that dictionaries cannot be sliced like lists and demonstrating the list(d.keys())[:n] pattern." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Title: Dictionary Slicing and Subsets. Content: Dictionaries are unordered and do not support slicing (e.g., d[:3] or d['a':'c'] will raise an error). To get the first N items, convert keys to a list: `keys = list(my_dict.keys())[:3]`. Then use a list comprehension: `subset = [my_dict[k] for k in keys]`.", + "why_helpful": "It directly addresses the specific technical trap in the question and explains the correct alternative shown in Option A.", + "why_maybe_unnecessary": "The student might find the answer if they simply memorize the past exam question, but they won't understand the underlying 'why'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:24:51Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q07", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q07", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "[1, 4, 3, 8, 5]", + "b": "[2, 4, 6, 8, 10]", + "c": "[1, 2, 3, 4, 5]", + "d": "[2, 2, 6, 4, 10]" + }, + "correct": "a", + "explanation": "The list comprehension doubles only the even numbers and leaves the odd numbers unchanged, so the result is [1, 4, 3, 8, 5].", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x * 2 if x % 2 == 0 else x for x in numbers]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question." + }, + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "Reinforces the logic of the modulo operator (i % 2 == 0) in a different context (while loops), helping a student confirm that this expression identifies even numbers." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This snippet is the only one that explicitly mentions 'list comprehension' and explains the modulo operator check (x % 2 == 0) for identifying even numbers, which are both core components of the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "Reinforces the logic of the modulo operator (i % 2 == 0) in a different context (while loops), helping a student confirm that this expression identifies even numbers.", + "critical_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-7-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets explain 'list comprehension' and the even-number check (% 2 == 0). However, they do not explain the ternary 'if-else' syntax within a comprehension (val if cond else other), which is the specific mapping logic used here. A student would have to infer that 'if' applies to the preceding expression.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate snippets cover list comprehensions with filters ([x for x in list if cond]) but lack examples of conditional mapping ([val_if if cond else val_else for x in list]).", + "missing_concepts": [ + "ternary operator / conditional expression syntax", + "conditional mapping in list comprehensions" + ], + "proposed_fix": "Add a snippet or piece that explains the 'value if condition else other_value' syntax, specifically within a list comprehension context." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet explaining 'Conditional Expressions in List Comprehensions'. Example: '[x * 2 if x > 2 else x for x in list] - This doubles items greater than 2 and keeps others the same.'", + "why_helpful": "This bridges the gap between simple filtering (which is in the current snippets) and the conditional mapping required by this specific question.", + "why_maybe_unnecessary": "A student might be able to guess the logic if they are familiar with 'if/else' in English, but the Python syntax 'val if cond else other' is counter-intuitive for beginners.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:26:18Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-5-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-trial_midterm-5-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB x = 'numbers'\nfor i, j in enumerate(x):\nif i % 2 !" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q08", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q08", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 2", + "question": "What is the output of the following code segment?", + "options": { + "a": "['10a', '30c']", + "b": "[10, 20, 30, 40]", + "c": "['a', 'b', 'c', 'd']", + "d": "['10a', '20b', '30c', '40d']" + }, + "correct": "a", + "explanation": "The loop keeps only even indices from enumerate(list1), so it uses indices 0 and 2 and appends the concatenated strings '10a' and '30c'.", + "code_context": "list1 = [10, 20, 30, 40]\nlist2 = ['a', 'b', 'c', 'd']\n\nresult = []\n\nfor index, value in enumerate(list1):\n if index % 2 == 0:\n result.append(str(value) + list2[index])\n\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Provides an example of the .append() method, which is used to build the result list in the code segment." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "While focused on DataFrames, the rationale explains the concept of using a 'boolean mask on the index to find even numbers', reinforcing the parity selection logic." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "rationale": "Necessary for understanding the % parity operator." + }, + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Necessary for understanding how append adds items to a list." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "This snippet explicitly demonstrates the modulo operator logic (i % 2 == 0) for identifying even numbers, which is the core conditional logic in the question.", + "critical_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Provides an example of the .append() method, which is used to build the result list in the code segment.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "While focused on DataFrames, the rationale explains the concept of using a 'boolean mask on the index to find even numbers', reinforcing the parity selection logic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "rationale": "Necessary for understanding the % parity operator.", + "needed_piece_ids": [ + "exam-midterm_2024-3-w2-loops" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Necessary for understanding how append adds items to a list.", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover the modulo operator and list appending, but there is no explanation of the enumerate() function, which is critical for knowing that the loop variable 'index' refers to the position and 'value' refers to the content.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The primary gap is the lack of information regarding the enumerate() function and the behavior of string concatenation with converted integers.", + "missing_concepts": [ + "enumerate() function behavior", + "string concatenation (str(value) + list2[index])" + ], + "proposed_fix": "Add a snippet or AI question entry explaining that enumerate(list) provides pairs of (index, value) during iteration." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add an AI common question for 'enumerate() function': 'What does enumerate(mylist) do in a for loop?' Explanation: It returns both the index (position) and the value of each item in the list. Example: for i, v in enumerate(['a', 'b']): i is 0,1 and v is 'a','b'.", + "why_helpful": "The question relies entirely on knowing that 'index' is the numerical position provided by enumerate.", + "why_maybe_unnecessary": "Some students might guess 'index' means position from the variable name, but it is not guaranteed.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:27:08Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-3-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-3-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ni = 1\nwhile True:\nif i % 2 == 0:\ni += 1\ncontinue\nelif i == 7:\nbreak\nelse:\nprint(i)\ni += 1\nWhich of the following code snippets will print the same output?\nA for i in range(1, 5, 2):\nprint(i)\nB for i in range(7, 1, -2):\nprint(i)\nC " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q09", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q09", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 2", + "question": "Suppose you have a list called mylist. You want to extract every third element starting from index 1 (inclusive) to the last index (inclusive) from that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\n\nthen executing the following command:\nprint(subset)\n\nshould return:\n[15, 30, 45]\n\nWhat should the blanks be filled with?", + "options": { + "a": "1:len(mylist):3", + "b": "0:len(mylist):3", + "c": "1:len(mylist)-1:3", + "d": "0:len(mylist)-1:3" + }, + "correct": "a", + "explanation": "Starting at index 1 and stepping by 3 gives positions 1, 4, and 7, which are 15, 30, and 45. Using len(mylist) as the stop value includes the last valid stepped element.", + "code_context": "subset = mylist[___:___:___]\nmylist = [10, 15, 20, 25, 30, 35, 40, 45]\nprint(subset)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-3", + "rationale": "This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded." + }, + "top_three_snippets": [ + { + "item_id": "aiq-3", + "rationale": "This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-3", + "rationale": "It is the only family in the candidate set that provides examples of list stepping and explains index-based exclusion logic." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-3", + "rationale": "This family contains the 'Sequences and Access' piece which explicitly demonstrates list slicing with step values (e.g., [::2]) and the 'Objects and Names' piece which explains the start/stop/step logic, including the critical fact that the 'stop' value is excluded.", + "critical_piece_ids": [ + "aiq-3" + ] + }, + "supporting_snippet_families": [], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-3", + "rationale": "It is the only family in the candidate set that provides examples of list stepping and explains index-based exclusion logic.", + "needed_piece_ids": [ + "aiq-3" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The necessary concepts (start position, step size, and 'stop' exclusion) are all present in the aiq-3 family. However, a student must synthesize the 'stop is excluded' rule from the range() piece and apply it to the slicing examples, as there isn't a single piece that defines the full [start:stop:step] syntax in one rule.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets lack a direct definition of the three-part list slicing syntax [start:stop:step] in a unified rule.", + "missing_concepts": [ + "Explicit definition of the list[start:stop:step] syntax", + "Direct rule stating that for slicing, index 'stop' is excluded" + ], + "proposed_fix": "Add a foundational snippet explaining list[start:stop:step] where start is inclusive, stop is exclusive, and step is the increment." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new rule snippet: 'List Slicing (Start:Stop:Step)'. Rule: Use list[start:stop:step] to extract elements. 'start' is the first index included; 'stop' is the boundary (not included); 'step' is how many indices to jump. Example: mylist[1:8:3] starts at index 1 and takes every 3rd element until index 7.", + "why_helpful": "This provides the exact structural knowledge needed to fill in the blanks without having to infer it from separate examples.", + "why_maybe_unnecessary": "A clever student might eliminate options b and d (starting at 0) and then use the 'stop is excluded' hint from range() to choose 'len(mylist)' over 'len(mylist)-1'.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:27:45Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:aiq-3", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\nApply the lambda/function to one element first, then extend that same transformation to the rest of the Series or iterable.\nExam • midterm_2023 • Q13\nSuppose you have the" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nExpand `range(start, stop, step)` manually; `stop` is excluded and the next value is found by adding `step` each time.\nExam • trial_midterm • Q1\nFor example:\nIf x = [1, 2, 4, 8]\nthe program should pri" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "What does `list(x.values()) + list(x.keys())` print?\nCheck whether membership is testing keys, and trace any lookup or mutation on the dictionary.\nExam • trial_midterm • Q10\nSuppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line o" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • midterm_2023 • Q9\nSuppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if " + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "list\nExam • midterm_2024 • Q22\nConsider the following code snippet:\nx = [\"a\", \"b\", \"c\", \"4\"]\nprint(x[-3] + x[3]*3)\nWhich of the following code snippet will print the same output?" + }, + { + "item_id": "aiq-3", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Correct. c: [::-1] reverses to [10,9,8,7,6,5,4,3,2,1], then [::2] takes every 2nd: [10,8,6,4,2]. Correct. d: [::2] gives [1,3,5,7," + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q10", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q10", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_1", + "question": "Suppose you have the following function:\n\nWhat will be printed by the following line of code?\nprint(main())", + "options": { + "a": "True", + "b": "False", + "c": "0", + "d": "None" + }, + "correct": "d", + "explanation": "The default value of x is 0, so neither if-condition runs and the function reaches the end without returning anything, which prints None.", + "code_context": "def main(x = 0):\n if x > 0:\n return True\n\n if x < 0:\n return False\n\nprint(main())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "Directly explains that if a function's return statement is not reached, it returns 'None'. This is the core concept tested by the question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "Directly explains that if a function's return statement is not reached, it returns 'None'. This is the core concept tested by the question." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Provides an example of default argument values (e.g., num2=10), which helps a student understand that 'x=0' in the definition means 'x' starts at 0 when the function is called without arguments." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "Covers the 'Implicit return None' behavior." + }, + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "rationale": "Covers default argument behavior." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "Directly explains that if a function's return statement is not reached, it returns 'None'. This is the core concept tested by the question.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "Provides an example of default argument values (e.g., num2=10), which helps a student understand that 'x=0' in the definition means 'x' starts at 0 when the function is called without arguments.", + "critical_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "Covers the 'Implicit return None' behavior.", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "rationale": "Covers default argument behavior.", + "needed_piece_ids": [ + "exam-midterm_2023-9-w3-arguments" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The combination of the default argument rule and the implicit return rule provides all necessary information to solve the question without prior knowledge.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The existing snippets are sufficient. The AI-generated 'Implicit return None' note is particularly effective for this question.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:28:07Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q11", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q11", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_3", + "question": "Suppose you have a variable called x which contains a list of integers as follows:\nx = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n\nWhich of the following lines will produce an output that is different from the rest?", + "options": { + "a": "print(len(x))", + "b": "print(sorted(x, reverse=True)[0])", + "c": "print(x.index(9))", + "d": "print(sum(x[4:6]))" + }, + "correct": "a", + "explanation": "len(x) is 10, while sorted(x, reverse=True)[0] is 9, x.index(9) is 9, and sum(x[4:6]) is 4 + 5 = 9.", + "code_context": "x = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Reinforces the explanation of reverse sorting and basic list operations." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of slicing syntax (`alphabet[1::2]`), which helps a student interpret the `x[4:6]` slice in option D." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This snippet explicitly explains how `sorted(x, reverse=True)` works by creating a set and sorting it in reverse, which is essential for evaluating option B.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Reinforces the explanation of reverse sorting and basic list operations.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of slicing syntax (`alphabet[1::2]`), which helps a student interpret the `x[4:6]` slice in option D.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets cover the complex `sorted` logic and provide context for slicing, they do not define the basic built-in functions `len()` and `sum()`, nor the list method `.index()`. A student with zero Python knowledge would have to rely on the English meaning of these words to guess their function.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to define several fundamental built-in functions and list methods used in the question options.", + "missing_concepts": [ + "len() function", + "sum() function", + "list.index() method" + ], + "proposed_fix": "Add a summary piece covering 'Common List Built-ins and Methods' that defines len, sum, and index." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new item explaining basic list operations: len(list) returns the count of items; sum(list) returns the total of numerical items; list.index(x) returns the position of the first occurrence of x.", + "why_helpful": "This would make the question fully answerable by defining the operations in options A, C, and D.", + "why_maybe_unnecessary": "These functions are named intuitively, but for a strict zero-knowledge context, they require formal definitions.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:28:50Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q12", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q12", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_1", + "question": "You want to write a function called main which accepts a flexible number of integers as arguments.\n\nThe function should return a dictionary with the following key-value pairs:\n- key 'sum' has a value which is the sum of all the integers passed as arguments\n- key 'pro' has a value which is the multiplicative product of all the integers passed as arguments\n- key 'pow' has a value which is a list of all the squares of the integers passed as arguments\n\nWhich of the following lines of code will complete the function to give what you need?", + "options": { + "a": "x['sum'] = sum(args)\nx['pro'] = 1\nx['pow'] = []\nfor i in args:\n x['pro'] *= i\n x['pow'].append(i**2)", + "b": "x['sum'] = sum(args)\nx['pro'] = i for i in args\nx['pow'] = [i**2 for i in args]", + "c": "for i in args:\n x['sum'] = sum(args)\n x['pro'] *= i\n x['pow'] = [i**2 for i in args]", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "Option A correctly stores the sum, initializes the product accumulator to 1 before multiplying through the arguments, and builds the list of squares for each integer.", + "code_context": "def main(*args):\n x = {}\n\n # missing lines\n # ...\n\n return x" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "Piece 2 (multiply function) is the most critical as it demonstrates exactly how to handle a flexible number of arguments (*args) and the accumulator pattern for multiplication (total = 1 followed by total *= num). This allows the student to identify why option 'a' correctly initializes 'pro' to 1." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "Piece 2 (multiply function) is the most critical as it demonstrates exactly how to handle a flexible number of arguments (*args) and the accumulator pattern for multiplication (total = 1 followed by total *= num). This allows the student to identify why option 'a' correctly initializes 'pro' to 1." + }, + { + "item_id": "aiq-5", + "rationale": "Piece 1 (summarize function) shows how to return a dictionary with calculated values (like sum(nums)) using specific keys, which directly helps with the 'sum' and overall dictionary structure requirement." + }, + { + "item_id": "aiq-2", + "rationale": "Piece 2 shows the .append() method, which is used in option 'a' to build the 'pow' list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "aiq-5", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "Piece 2 (multiply function) is the most critical as it demonstrates exactly how to handle a flexible number of arguments (*args) and the accumulator pattern for multiplication (total = 1 followed by total *= num). This allows the student to identify why option 'a' correctly initializes 'pro' to 1.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "rationale": "Piece 1 (summarize function) shows how to return a dictionary with calculated values (like sum(nums)) using specific keys, which directly helps with the 'sum' and overall dictionary structure requirement.", + "critical_piece_ids": [ + "aiq-5" + ] + }, + { + "snippet_id": "item:aiq-2", + "rationale": "Piece 2 shows the .append() method, which is used in option 'a' to build the 'pow' list.", + "critical_piece_ids": [ + "aiq-2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "Between aiq-4 and aiq-5, the student has examples of flexible arguments, dictionary construction, sum() usage, and the multiplication accumulator pattern. Option 'a' is the only one that uses the correct initialization (x['pro'] = 1) shown in the snippets.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic for sum and product is well-covered, the exponent operator (**) and initializing a dictionary key to an empty list are not explicitly demonstrated in a single context.", + "missing_concepts": [ + "exponent operator (**)", + "initializing an empty list inside a dictionary key" + ], + "proposed_fix": "Add a snippet or piece that demonstrates list building within a loop for squares or powers." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet piece showing: `results['squares'] = []; for i in numbers: results['squares'].append(i**2)`.", + "why_helpful": "It would explicitly cover the 'pow' list generation logic (initialization + append + exponent).", + "why_maybe_unnecessary": "Students might infer the power operator or recognize option 'a' as the only one with correct product logic.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:29:12Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 29, + "candidate_snippet_families": [ + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-10-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-10-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\narguments.\nThe function should return a dictionary with name, age, and all other key-value pairs that may be passed as keyword arguments." + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Mutable arguments\nMutating a passed list changes the caller's object; rebinding the parameter does not.\nMutable arguments" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q13", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q13", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 2", + "question": "You have the following objects loaded in Python:\nitem = \"laptop\"\nprice = 1299.99\n\nYou need to print the following sentence:\nThe laptop is priced at $1299.99.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(message)", + "b": "message = \"The {0} is priced at ${1}.\".format(item, price)\nprint(mesage)", + "c": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)", + "d": "message = \"The {item} costs ${price}.\".format(price, item)\nprint(message)" + }, + "correct": "a", + "explanation": "Option A correctly uses positional placeholders and prints the defined variable `message`. Option B appears to use a misspelled variable name in the print call, and C/D mix named placeholders with positional arguments.", + "code_context": "item = \"laptop\"\nprice = 1299.99" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Mentions a specific string format (for a URL), but relates to the data format rather than the Python .format() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a basic print statement; however, it provides no help with the actual core of the question (string formatting)." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "While entirely insufficient for the specific logic of string formatting, this is one of the few snippets that demonstrates a basic print() call and variable usage, which is the only overlapping concept with the question.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "Mentions a specific string format (for a URL), but relates to the data format rather than the Python .format() method.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a basic print statement; however, it provides no help with the actual core of the question (string formatting).", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets cover string formatting techniques such as f-strings or the .format() method. The question specifically tests positional placeholders ({0}, {1}) and argument mapping in .format(), as well as recognizing variable name typos. The provided snippets focus on dictionaries, lists, and function arguments (**kwargs), which are unrelated.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Complete absence of documentation regarding string formatting and interpolation.", + "missing_concepts": [ + "The .format() method syntax", + "Positional placeholders ({0}, {1}) in strings", + "Argument mapping order in .format()", + "Basic variable name matching and typo detection" + ], + "proposed_fix": "Add a foundational snippet (from Week 1 or 2) that explicitly demonstrates f-strings and the .format() method, including how indices map to arguments." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet family 'String Formatting' with a piece showing: 1. .format() usage: 'Hello {0}, you have {1} messages'.format(name, count). 2. f-string usage: f'Hello {name}'. 3. Explicitly state that {0} refers to the first argument and {1} to the second.", + "why_helpful": "This question is a direct test of the .format() syntax and index mapping. Without a snippet explaining this, a student with no prior knowledge cannot distinguish between the correct positional mapping and the incorrect named/mixed options.", + "why_maybe_unnecessary": "If the cheat sheet is intended only for advanced data structures, this might be considered too 'basic', but it is clearly necessary for this specific exam question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:29:40Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q14", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q14", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 1", + "question": "Suppose you have run the following block of code:\n\nimport pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)\n\nWhich of the following lines of code give(s) the following output?\n1 4\n2 5\n3 6\nName: B, dtype: int64", + "options": { + "a": "df.loc[:, 'B']", + "b": "df['B'].loc[:]", + "c": "df['B']", + "d": "All of the given lines." + }, + "correct": "d", + "explanation": "Each of A, B, and C selects the same Series containing column `B`, so the correct choice is that all listed lines produce the shown output.", + "code_context": "import pandas as pd\ndata = {'A': [1, 2, 3],\n 'B': [4, 5, 6],\n 'C': [7, 8, 9]}\ndf = pd.DataFrame(data)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This snippet involves creating columns based on existing ones, which likely demonstrates the df['col'] syntax used in option C." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Mentions keeping specific columns when creating a new DataFrame, reinforcing the concept of column selection." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "This snippet mentions using .loc to select a specific column ('B'), which is relevant to understanding the syntax in option A, even though the snippet includes additional row filtering.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "This snippet involves creating columns based on existing ones, which likely demonstrates the df['col'] syntax used in option C.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "rationale": "Mentions keeping specific columns when creating a new DataFrame, reinforcing the concept of column selection.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets show examples of column access (df['A']) and filtered access (df.loc[...]), they do not explicitly teach the equivalence of df['B'], df.loc[:, 'B'], and df['B'].loc[:]. A student without prior knowledge would likely recognize df['B'] but would not have enough information to confirm that the other two syntaxes produce the exact same result.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing a clear explanation of pandas indexing equivalence rules for Series selection.", + "missing_concepts": [ + "Equivalence of bracket notation (df['col']) and .loc for column selection (df.loc[:, 'col'])", + "Understanding that .loc[:] on a Series is a redundant/identity operation", + "Fundamental difference between selecting a Series (column) and a DataFrame (subset)" + ], + "proposed_fix": "Add a foundational Pandas snippet specifically illustrating 'Equivalent Selection Methods' for columns, showing that basic brackets, .loc with a colon, and chained identity slices all return the same Series." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet 'Pandas Indexing: Column Retrieval' that explicitly lists df['B'], df.loc[:, 'B'], and s.loc[:] as valid/equivalent ways to interact with column data.", + "why_helpful": "This covers the 'trick' nature of the question where multiple syntaxes lead to the same result.", + "why_maybe_unnecessary": "It's a very specific syntax rule, but crucial for answering 'all of the above' questions in Pandas.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:30:06Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-7-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "Which of the following code lines could NOT have created df2 from df1?\nA\nB\nC\nD\nA\nOption A would sort all 5 rows of df1 and keep columns A, C, D, resulting in a 5-row DataFrame. df2 only has 3 rows (indices 4, 3, 2)." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q15", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q15", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_1", + "question": "Which code segment gives the same output as the following?\n\ndate = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))\n\nYou may assume that datetime and timedelta classess are already imported from the datetime module.", + "options": { + "a": "print(datetime.strptime('22-05-2023', '%d.%m.%Y'))", + "b": "print('02-05-2023')", + "c": "print(datetime.strptime('05.22.2023', '%d-%m-%Y'))", + "d": "date = datetime.strptime('10/05/2023', '%d/%m/%Y')\nprint((date + timedelta(days=5)).strftime('%m-%d-%Y'))" + }, + "correct": "b", + "explanation": "The original code parses May 12, 2023 and subtracts 10 days, so the printed result is the string `02-05-2023`.", + "code_context": "date = datetime.strptime(\"05.12.2023\", \"%m.%d.%Y\")\nprint((date + timedelta(days=-10)).strftime(\"%d-%m-%Y\"))" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Provides the fundamental definition of the print function, which is necessary to understand that the code's purpose is to output a specific string to the screen." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet belonging to the Datetime topic. It confirms the relationship between datetime objects and timedelta, which is used in the question for date arithmetic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Provides the fundamental definition of the print function, which is necessary to understand that the code's purpose is to output a specific string to the screen.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "", + "needed_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "A student with zero Python knowledge cannot determine the output without knowing what the format codes '%m', '%d', and '%Y' represent. Specifically, they cannot know if '05.12' is May 12 or December 5, nor can they know how timedelta(days=-10) behaves without explicit documentation of those parameters.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Existing snippets mention the existence of the Datetime module but do not define the specific syntax for parsing/formatting dates or the available attributes for timedelta initialization.", + "missing_concepts": [ + "datetime.strptime and datetime.strftime format codes (%d, %m, %Y)", + "Initialization parameters for timedelta (e.g., days=X)" + ], + "proposed_fix": "Add a lecture-based or reference snippet that defines common strftime/strptime format codes and provides a basic example of date arithmetic using timedelta." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a reference item for the datetime module: 'strptime(string, format)' and 'strftime(format)' with a table: %d (Day 01-31), %m (Month 01-12), %Y (Year 2023). Also define timedelta(days=n) for adding/subtracting days.", + "why_helpful": "This provides the 'dictionary' needed to translate the code into human-readable logic (May 12 - 10 days = May 02).", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:30:33Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n
                          • A function is a grouping of code that can perform a certain task and can be re-used \n
                          • Print is a built-in function, tha" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q16", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q16", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 16, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Easy_3", + "question": "You have the following definition for a class called Shape:\n\nWhat would be the output if we execute the following commands?\n\nprint(Shape(5, 3).area == Shape(1, 15).length)", + "options": { + "a": "True", + "b": "False", + "c": "An error", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "`Shape(5, 3).area` is `5 * 3 = 15`, and `Shape(1, 15).length` is `15`, so the comparison evaluates to `True`.", + "code_context": "class Shape:\n def __init__(self, height, length):\n self.height = height\n self.length = length\n self.area = self.height * self.length\n\nprint(Shape(5, 3).area == Shape(1, 15).length)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables." + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "Demonstrates the evaluation of equality (==) and logic in print statements, confirming that the output of such comparisons in Python is a boolean (True/False)." + }, + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Shows the syntax for instantiating a class with multiple arguments (Flight(...)), which helps clarify the 'Shape(5, 3)' part of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This piece describes the definition of a class with multiple attributes initialized in the constructor (__init__), which directly mirrors the structure of the Shape class and helps the student understand how arguments map to instance variables.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "rationale": "Demonstrates the evaluation of equality (==) and logic in print statements, confirming that the output of such comparisons in Python is a boolean (True/False).", + "critical_piece_ids": [ + "exam-midterm_2024-2-w2-conditions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "rationale": "Shows the syntax for instantiating a class with multiple arguments (Flight(...)), which helps clarify the 'Shape(5, 3)' part of the question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-1-w4-oop-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2024-2-w2-conditions" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the snippets explain class definition, initialization, and boolean output, they don't explicitly show the 'dot notation' (e.g., .area) being used directly on a newly created instance. A student must infer that Shape(5, 3).area refers to the attribute created inside __init__.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The candidate snippets are mostly exam prompts rather than direct reference material. They provide enough clues for a logical student to infer the answer, but they lack a concise explanation of attribute access on instance objects.", + "missing_concepts": [ + "Accessing attributes via dot notation on temporary instances", + "Explicit explanation of 'self' inside calculations in __init__" + ], + "proposed_fix": "Add a foundational reference snippet that explains the lifecycle: Class Call -> __init__ execution -> Attribute storage -> Dot notation retrieval." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Reference: OOP Basics. Calling Shape(5, 3) executes the __init__ method where arguments are assigned to self.attributes (e.g., self.area = 5*3). You can immediately access these using dot notation: Shape(5, 3).area.", + "why_helpful": "It directly explains the composite expression in the print statement which is the primary hurdle for a novice.", + "why_maybe_unnecessary": "The Vehicle class prompt already mentions that attributes are initialized at the time of object construction, which is a strong hint.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:31:05Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-2-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-midterm_2024-2-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA True\nB False\nC The code will result in an error.\nD 3" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-4-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-4-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == int(z)) or (x != y and y != z))\nA 3\nB The code will result in an error.\nC False\nD True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Given the class definition above, trying to execute the following two code lines will result in a Python error.\nmy_flight = Flight(\"KLM\", \"Amsterdam\", \"Paris\") # Code line 1\nmy_flight.set_date(my_flight, \"29-02-2022\") # Code line 2\n\nWhy" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q17", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q17", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 17, + "status": "completed", + "question_snapshot": { + "topic": "6-string - operations - 2", + "question": "Write a function called shuffle_sentence that takes a string as an argument and returns a new string where the words are shuffled randomly.\n\nFor example, if your function is called as:\nshuffle_sentence(\"Hello, how are you today?\")\nthen it could return a shuffled string like:\n'how today? you Hello, are'\n\nWhich of the following programs work(s) according to the requirements?\n\nHints:\nThe shuffle() function is a method from the random module. The shuffle() method takes a sequence, like a list, and reorganizes the order of the items. This method changes the original list; it does not return a new list.\nThe reversed() function computes the reverse of a given sequence object and returns it in the form of a list.", + "options": { + "a": "def shuffle_sentence(sentence):\n words = sentence.split()\n return ' '.join(reversed(words))", + "b": "import random\n\ndef shuffle_sentence(sentence):\n words = sentence.split()\n random.shuffle(words)\n return ' '.join(words)", + "c": "Both of the programs work.", + "d": "Neither of the programs work." + }, + "correct": "b", + "explanation": "Option B is the only one that actually shuffles the words randomly. Option A only reverses the word order, which does not satisfy the random-shuffle requirement.", + "code_context": "shuffle_sentence(\"Hello, how are you today?\")\n# could return: 'how today? you Hello, are'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-2", + "rationale": "This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it)." + }, + "top_three_snippets": [ + { + "item_id": "aiq-2", + "rationale": "This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it)." + }, + { + "item_id": "aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions without an explicit return (or returning None) result in None, which helps clarify the hint that shuffle() does not return a new list." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-2", + "rationale": "" + }, + { + "item_id": "aiq-4", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-2", + "rationale": "This snippet contains the 'List method effects' piece which explicitly instructs students to check if a method mutates a list in place, which is the core concept needed to understand why random.shuffle(words) works (it modifies the list and doesn't return it).", + "critical_piece_ids": [ + "aiq-2" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "The 'Return Behavior' piece explains that functions without an explicit return (or returning None) result in None, which helps clarify the hint that shuffle() does not return a new list.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets help explain 'in-place mutation' and 'None return values', which are the 'traps' of the question. However, they do not provide any information on string split() or join() methods, which are required to understand the code structure. The question's internal hints are actually more helpful for the shuffle() behavior than the snippets.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The snippets cover the logic of mutation but miss the specific string-list conversion methods used in both options.", + "missing_concepts": [ + "str.split()", + "str.join(list)" + ], + "proposed_fix": "Add a snippet demonstrating how to convert a sentence into a list of words using split() and how to recombine them into a string using join()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Topic: String Operations. Description: Use 'text.split()' to turn a string into a list of words. Use '\" \".join(words)' to combine a list of strings into one string separated by spaces.", + "why_helpful": "The question relies on understanding how words are converted to a list for shuffling and then back to a string for the return value.", + "why_maybe_unnecessary": "The student might guess the meaning of split and join from the context of the word 'shuffle_sentence', but it is a significant leap for someone with zero knowledge.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:31:28Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Mutable arguments\nMutating a passed list changes the caller's object; rebinding the parameter does not.\nMutable arguments" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Generators and Iterators", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q18", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q18", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 18, + "status": "completed", + "question_snapshot": { + "topic": "6-strings - find & replace - 1", + "question": "Consider the following line of code:\n\ntext = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\n\nYou want to create a new string called new_text where all occurances of \"oil\" are replaced by \"natural gas\".\n\nSo:\nprint(new_text)\nshould return:\n\"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "new_text = ' '.join([word if word != 'oil' else 'natural gas' for word in text.split()])", + "b": "new_text = text.replace(\"oil\", \"natural gas\")", + "c": "new_text = text.split()\nfor index, word in enumerate(new_text):\n if word == 'oil':\n new_text[index] = 'natural gas'\nnew_text = ' '.join(new_text)", + "d": "All of the given options works as intended." + }, + "correct": "d", + "explanation": "All three code fragments replace each occurrence of the standalone word `oil` with `natural gas`, so the correct answer is that all of them achieve the requested result.", + "code_context": "text = \"The demand for oil has been increasing. Natural gas is a crucial commodity in many industries. The price of oil has also been rising.\"\nprint(new_text)\n# should return:\n# \"The demand for natural gas has been increasing. Natural gas is a crucial commodity in many industries. The price of natural gas has also been rising.\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Involves string formatting and character separation, providing a basic context for string-based function arguments." + }, + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Involves checking string properties (anagrams), which relates to the conditional logic used in option 'a' and 'c' of the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "This is the only snippet that explicitly mentions processing a string in a structured way (extracting parts of a URL), which is the closest available concept to string manipulation and find/replace logic.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "Involves string formatting and character separation, providing a basic context for string-based function arguments.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "rationale": "Involves checking string properties (anagrams), which relates to the conditional logic used in option 'a' and 'c' of the question.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-4-w2-conditions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "high", + "rationale": "The candidate snippets focus on dictionaries, functions, and Pandas. There is zero mention of the .replace(), .split(), or .join() string methods, nor is there an explanation of list comprehensions or the enumerate() function, all of which are critical to evaluating the four options.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The knowledge base is missing foundational string manipulation methods and advanced iteration patterns (list comprehensions).", + "missing_concepts": [ + "str.replace(old, new) method", + "str.split() method for breaking strings into words", + "' '.join(list) method for combining words", + "List comprehensions with if-else logic", + "enumerate() for tracking list indices during iteration" + ], + "proposed_fix": "Add a dedicated snippet family for 'String Methods' and another for 'Iterables and List Comprehensions' containing examples of find/replace patterns." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet for Week 1/4 'Common String Operations' that demonstrates .replace(), .split(), and .join() using a simple text example.", + "why_helpful": "The question directly tests the equivalence of using these three methods to achieve the same result.", + "why_maybe_unnecessary": "The topic might be covered in lecture slides, but it is currently absent from the selectable 'key point' snippets.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:31:55Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q19", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q19", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 19, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - hard - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000\n\nYou need to perform a series of operations on this DataFrame.\n- Operation 1: Select all rows where the age is greater than 30 and the gender is \"Male\".\n- Operation 2: Create a new column called Sex_abbr of which the values should be \"F\" if gender is \"Female\" and \"M\" if gender is \"Male\".\n- Operation 3: Calculate the average salary of all employees.\n\nWhich of the following blocks of code performs these operations as intended?", + "options": { + "a": "df_operation1 = df[(df['Age'] > 30) & (df['Gender'] == 'Male')]\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "b": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = ['M' if x == 'Male' else 'F' for x in df['Gender']]\ndf_operation3 = df['Salary'].mean()", + "c": "df_operation1 = df.loc(df['Age'] > 30) & df.loc(df['Gender'] == 'Male')\ndf['Sex_abbr'] = df['Gender'].map(lambda x: 'M' if x == 'Male' else 'F')\ndf_operation3 = df['Salary'].sum()/len(df)", + "d": "df_operation1 = df[df['Age'] > 30 & df['Gender'] == 'Male']\ndf['Sex_abbr'].map(lambda x: 'M' if x == 'Male' else 'F' for x in df['Gender'])\ndf_operation3 = df['Salary'].sum()/len(df)" + }, + "correct": "a", + "explanation": "Option A correctly filters rows with both conditions using boolean masking, builds the abbreviation column from the Gender column, and computes the average salary with mean().", + "code_context": "Name Age Gender Salary\n0 John 25 Male 50000\n1 Jane 30 Female 65000\n2 Alex 35 Male 80000\n3 Lisa 40 Female 70000\n4 Mark 28 Male 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions 'boolean mask', providing a conceptual link to row selection (Operation 1), though it lacks the specific syntax for multiple conditions." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions calculating the 'mean' of a pandas Series, which is the direct requirement for Operation 3." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Shows the fundamental syntax for creating a new column in a pandas DataFrame (df['C'] = ...), which helps a student understand the structure of Operation 2.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Mentions 'boolean mask', providing a conceptual link to row selection (Operation 1), though it lacks the specific syntax for multiple conditions.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions calculating the 'mean' of a pandas Series, which is the direct requirement for Operation 3.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The snippets provide the high-level concepts (column creation, boolean masks, mean) but fail to show the specific syntax required for 'hard' pandas operations: 1) The use of bitwise '&' with mandatory parentheses for multiple filter conditions, and 2) The syntax for list comprehensions or lambda mapping used to derive new column values. A zero-knowledge student could guess based on keywords but wouldn't know why option 'a' is syntactically superior to 'd' (operator precedence) or 'b/c' (accessor syntax).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Critical syntax for multi-condition filtering and conditional column creation is missing.", + "missing_concepts": [ + "Pandas multi-condition boolean masking (using '&' and '|' with required parentheses)", + "Derived column creation using list comprehensions with if/else (ternary) logic", + "Correct accessor syntax for .loc vs standard brackets []" + ], + "proposed_fix": "Add a new snippet covering complex pandas selections and transformations." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet 'Pandas Advanced Selection and Derived Columns' containing: 1. df[(df['A'] > x) & (df['B'] == y)] (emphasize parentheses), 2. df['new'] = ['val1' if x == 'y' else 'val2' for x in df['old']], 3. df['col'].mean().", + "why_helpful": "Directly addresses the syntax patterns used in this 'hard' level question, particularly the tricky operator precedence in filtering and the list comprehension pattern.", + "why_maybe_unnecessary": "If the cheat sheet is only intended for beginner-level pandas, this might be deemed too advanced, but it is necessary for this specific exam question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:32:24Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q20", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q20", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 20, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - lambda - 1", + "question": "Consider the following pandas DataFrame called df:\n\n Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000\n\nYou want to create a new column called Bonus that compute each employee's bonus based on their salary and performance review using the following formula:\n- if the performance review is less than 4, the bonus is 0.\n- if the performance review is 4 or 5, the bonus is 5% of the salary.\n\nWhich of the following code snippets works as intended?", + "options": { + "a": "df['Bonus'] = df.apply(lambda row: row['Salary']*0.05 if row['Performance_review']>=4 else 0, axis=1)", + "b": "df['Bonus'] = df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>=4 else 0)", + "c": "df['Bonus'] = map(df['Salary'].apply(lambda x: x*0.05 if df['Performance_review']>4 else 0))", + "d": "df['Bonus'] = df['Salary'].map(lambda row: row*0.05 if df['Performance_review']>=4 else 0)" + }, + "correct": "a", + "explanation": "Option A evaluates each row, checks the row's Performance_review value, and returns either 5% of Salary or 0 for that employee.", + "code_context": "Name Performance_review Salary\n0 John 2 50000\n1 Jane 4 65000\n2 Alex 3 80000\n3 Lisa 2 70000\n4 Mark 1 55000" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the fundamental syntax for creating a new column ('C') in a DataFrame from existing columns ('A' and 'B'), which helps a student understand the 'df['Bonus'] = ...' structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "This snippet introduces the concept of applying a function to elements using a mapping method (.map()), which establishes the logic for using lambda functions to transform data, even if it doesn't cover the row-wise DataFrame context.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "Demonstrates the fundamental syntax for creating a new column ('C') in a DataFrame from existing columns ('A' and 'B'), which helps a student understand the 'df['Bonus'] = ...' structure.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets cover basic column creation and the concept of mapping functions, they do not explain the 'axis=1' parameter or the specific 'lambda row' pattern required to access multiple columns at once. A student with zero prior knowledge would likely struggle to distinguish between using .apply() on the DataFrame vs. using .map() or .apply() on a single column.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no information explaining row-wise operations involving multiple columns, specifically the 'axis=1' parameter in .apply().", + "missing_concepts": [ + "df.apply(axis=1) for row-wise manipulation", + "Using lambda row to access multiple column values simultaneously", + "Difference between Series.map() and DataFrame.apply(axis=1)" + ], + "proposed_fix": "Add a snippet to Week 5 (Pandas) that explicitly shows how to calculate a new column based on conditions across two or more other columns using .apply(axis=1)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a piece to Topic: 'Working With Values' (Week 5): 'Row-wise Operations: To create a column based on values in multiple columns, use df.apply(lambda row: func(row[\"Col1\"], row[\"Col2\"]), axis=1). The axis=1 argument ensures the function sees each row as an object, allowing you to access any column inside the lambda.'", + "why_helpful": "This directly explains the 'axis=1' and 'lambda row' syntax which are the keys to identifying the correct answer in this common exam question pattern.", + "why_maybe_unnecessary": "Only if the curriculum expects students to intuit row-wise application from basic series mapping, which is highly unlikely for beginners.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:33:14Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "snippet_label": "Working With Values", + "week": 5, + "topic": "Working With Values", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-8-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "You have a Series s with municipality and province names separated by \"; \". You'd like to create a new Series that only contains the municipality names. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nThe .map() method allows applying a function (like spli" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q21", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q21", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 21, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Function_3", + "question": "You want to create a function called main which take an integer and a flexible number of strings as arguments. The strings represent dates in the format of DD MM YYYY. The day, month and year can be separated by different characters.\n\nYour function should look for the string inputs which represent dates as DD-MM-YYYY or DD/MM/YYYY and return those strings in the format of DD.MM.YYYY in a list. Furthermore, the dates represented by the strings should be shifted by the amount of days as given by the integer argument.\n\nFor example, if we call your function as:\nmain(3, '25/06/2003', '26.06.2003', '27-06-2003', '28:06:2023', '29-06-2023', '30.06.2023')\n\nthe output should be:\n['28.06.2003', '30.06.2003', '02.07.2023']\n\nTake a look at the following code segment. Does it do what is intended? If not, then why not?", + "options": { + "a": "The code segment works as intended.", + "b": "This code segment does not work because the function will return a list of datetime objects, not a list of strings representing dates.", + "c": "This code segment does not work because the strftime() method cannot be applied to NoneType object.", + "d": "This code segment produces an error because you cannot concatenate strings and timedelta." + }, + "correct": "b", + "explanation": "The function parses matching inputs and adds the day offset, but it appends datetime objects and never converts them back to strings in DD.MM.YYYY format before returning.", + "code_context": "def main(delta, *args):\n dates = []\n for string in args:\n if '-' in string:\n dates.append(datetime.strptime(string, '%d-%m-%Y') + timedelta(days=delta))\n elif '/' in string:\n dates.append(datetime.strptime(string, '%d/%m/%Y') + timedelta(days=delta))\n else:\n dates.append(None)\n return [date for date in dates if type(date) != None]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Provides a practical example of a function using *args to filter and process a flexible number of inputs, mirroring the structure of the exam question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "This family provides the most relevant syntactical context, specifically explaining the *args (flexible positional arguments) used in the function signature.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "Provides a practical example of a function using *args to filter and process a flexible number of inputs, mirroring the structure of the exam question.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "medium", + "rationale": "The snippets explain function syntax and flexible arguments (*args), but there is zero information regarding the datetime module. A student with no prior knowledge wouldn't know that datetime.strptime returns an object or that timedelta addition results in another datetime object, which is the core of the question (distinguishing between objects and strings).", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Complete absence of datetime module documentation or usage examples.", + "missing_concepts": [ + "datetime.strptime (parsing strings to datetime objects)", + "datetime.strftime (formatting datetime objects to strings)", + "timedelta (representing and adding time durations)", + "Difference between datetime objects and string representations of dates" + ], + "proposed_fix": "Add a new snippet or key point explaining the datetime module workflow: String -> strptime -> Object -> arithmetic with timedelta -> strftime -> String." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a Datetime Basics snippet: 'To process dates, use datetime.strptime(string, format) to create a datetime object. To go back to a string, use object.strftime(format). Use timedelta(days=n) to shift dates. strptime returns an object, not a string.'", + "why_helpful": "This directly enables the student to see that the provided code segment stops at the 'Object' phase and fails to perform the final 'strftime' conversion to strings required by the question.", + "why_maybe_unnecessary": "If the student somehow infers from the options that 'datetime objects' are a distinct type from strings, they might guess 'b', but they wouldn't know for sure.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:33:41Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 24, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ai-example-8", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually availabl" + }, + { + "item_id": "ai-example-5", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "import module does not create bare globals\nclear_names()\n\nfrom extension import create_absolute_year as cay\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(cay(1))\nexcept Exception as e:\n print(e)\nKeep track of which name is actually" + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import r" + }, + { + "item_id": "ai-example-2", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Direct import plus alias binds both names\nclear_names()\n\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `import`, `from ..." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q22", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q22", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 22, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Hard_2", + "question": "You want to define a class called Calendar, which has four attributes that are initialized at the time of object construction:\n1. The 'event' attribute can be any string,\n2. The 'date' attribute is a string representing a date as 'DD-MM-YYYY',\n3. The 'start' attribute is a string representing the time as 'HH:MM', and\n4. The 'length' attribute is an integer representing the amount of minutes.\n\nThe class should also have a method called get_details() that gives a description of Calendar objects.\n\nFor example, if we execute the following commands;\nevent1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n\nthe output should be:\nCoffee meeting: 01-06-2023, 9:30-9:50.\n\nWhich of the following code segments gives you what you want?", + "options": { + "a": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start = datetime(self.date.year, self.date.month, self.date.day, int(start.split(':')[0]), int(start.split(':')[1]))\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "b": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.split(':')[0], minute=start.split(':')[1])\n self.length = timedelta(minutes=length)\n self.end = self.start + self.length\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "c": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = date\n self.start = datetime(self.date, hour=start.hour, minute=start.minute)\n self.end = self.self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'", + "d": "class Calendar():\n def __init__(self, event, date, start, length):\n self.event = event\n self.date = datetime.strptime(date, '%d-%m-%Y')\n self.start.hour = start.hour\n self.start.minute = start.minute\n self.end = self.start + timedelta(minutes=length)\n def get_details(self):\n return f'{self.event}: {self.date.strftime(\"%d-%m-%Y\")}, {self.start.hour}:{self.start.minute}-{self.end.hour}:{self.end.minute}.'" + }, + "correct": "a", + "explanation": "Option A is the only choice that correctly parses the date string, combines the parsed date with the split start time to build a datetime, adds the duration in minutes, and formats the requested details string.", + "code_context": "event1 = Calendar('Coffee meeting', '01-06-2023', '9:30', 20)\nprint(event1.get_details())\n# output:\n# Coffee meeting: 01-06-2023, 9:30-9:50." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the basic syntax for class definitions and the __init__ method which is required to evaluate the structure of the options." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows basic string formatting within a print/text context, which helps understanding the get_details() method structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "It is the only snippet that mentions the datetime module and the concept of timedelta, which are central to the question's logic.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the basic syntax for class definitions and the __init__ method which is required to evaluate the structure of the options.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Shows basic string formatting within a print/text context, which helps understanding the get_details() method structure.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While the snippets cover basic OOP and mention the existence of datetime/timedelta, they do not explain the strptime() and strftime() methods, nor how to instantiate a datetime object with specific hour/minute parameters or use split() on strings. A student with zero knowledge would not be able to confidently select Option A over the syntactically plausible but incorrect alternatives.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The provided snippets lack coverage of datetime string parsing and formatting, and basic string splitting.", + "missing_concepts": [ + "datetime.strptime()", + "datetime.strftime()", + "string.split()", + "timedelta(minutes=...)", + "datetime object attribute access (.hour, .minute)" + ], + "proposed_fix": "Add a snippet family for Datetime Manipulation that explicitly shows parsing strings into datetimes, formatting them back to strings, and performing arithmetic with specific timedelta units (minutes, hours)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet demonstrating: 'dt = datetime.strptime(\"01-01-2023\", \"%d-%m-%Y\")', 'new_dt = dt + timedelta(minutes=30)', and 'print(new_dt.strftime(\"%H:%M\"))'.", + "why_helpful": "This would directly address the core difficulty of the question: converting strings to datetime objects and performing duration math.", + "why_maybe_unnecessary": "If the course expects students to memorize these standard library methods, but for a 'zero knowledge' student, this is a hard requirement.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:34:26Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "snippet_label": "Datetime", + "week": 6, + "topic": "Datetime", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Datetime", + "subtopic_title": "", + "search_text": "Which of the following code segments will return the number of the day (1-366) that a datetime value represents within the year?\nA\nB\nC\nD\nA\nSubtracting two datetime objects results in a timedelta object. Accessing the .days attribute gives the difference as an integer. Adding 1 ma" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q23", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q23", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 23, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Function_2", + "question": "You have the following definition for a class called Employee:\n\nclass Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nYou want to add three methods to this class:\n1. The holiday_bonus() method which computes and returns the holiday bonus, which is 8.0% of the yearly salary,\n2. The year_end_bonus() method which computes and returns the year end bonus, which is 8.3% of the yearly salary\n3. The payment_overview() method which returns a payment overview of the employee using the following format:\n[Name] receives $[salary] monthly, $[holiday bonus] in May and $[year end bonus] in December.\n\nFor example, if we execute the following commands:\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())\n\nthe output should be:\n2400.0\n2490.0\nJohn Smith receives $2500 monthly, $2400.0 in May and $2490.0 in December.\n\nWhich of the following code segments should you place on the blank in the class definition to achieve what you want?", + "options": { + "a": "def holiday_bonus(self):\n return self.salary * 12 * 0.080\ndef year_end_bonus(self):\n return self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus()} in May and ${self.year_end_bonus()} in December.'", + "b": "def payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.salary*12*0.08} in May and ${self.salary*12*0.083} in December.'", + "c": "def holiday_bonus():\n self.holiday_bonus = self.salary * 12 * 0.080\ndef year_end_bonus():\n self.year_end_bonus = self.salary * 12 * 0.083\ndef payment_overview(self):\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'", + "d": "def payment_overview(self):\n self.holiday_bonus = self.salary * 12 * 0.080\n self.year_end_bonus = self.salary * 12 * 0.083\n return f'{self.name} receives ${self.salary} monthly, ${self.holiday_bonus} in May and ${self.year_end_bonus} in December.'" + }, + "correct": "a", + "explanation": "Option A defines all three requested methods, computes the two bonuses from the yearly salary, and uses those method results in the overview string.", + "code_context": "class Employee:\n def __init__(self, name, role, salary):\n self.name = name\n self.role = role\n self.salary = salary\n # ...\n\nemployee1 = Employee('John Smith', 'HR representative', 2500)\nprint(employee1.holiday_bonus())\nprint(employee1.year_end_bonus())\nprint(employee1.payment_overview())" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining a class and initializing attributes (name, mode), helping the student understand the 'self' syntax and attribute access used in the Employee class." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string formatting with variables and rounding, which is necessary for constructing the 'payment_overview' method return string." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "This snippet explicitly discusses writing a method ('compare') that performs logic using object attributes, which mirrors the task of adding bonus and overview methods to the Employee class.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "Provides the foundational syntax for defining a class and initializing attributes (name, mode), helping the student understand the 'self' syntax and attribute access used in the Employee class.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "Demonstrates string formatting with variables and rounding, which is necessary for constructing the 'payment_overview' method return string.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class structure, attribute access, and string formatting. However, they do not explicitly show a method calling another method within the same class using 'self.method()', which is the critical syntax required to distinguish Option A from the others. A student might not know if they should use parentheses or if variables like 'self.holiday_bonus' (Option C/D) are sufficient.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "Missing a clear example of 'internal method delegation'—where one instance method calls another instance method of the same object.", + "missing_concepts": [ + "method-to-method calling syntax (self.method_name())", + "difference between instance attributes and instance methods" + ], + "proposed_fix": "Add an OOP snippet showing a class like 'Receipt' with a 'get_tax()' method and a 'get_total()' method that calls 'self.get_tax()'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet for OOP Methods showing: class Order: def get_tax(self): return self.price * 0.1; def get_total(self): return self.price + self.get_tax().", + "why_helpful": "This would directly demonstrate how to call one method from another using the self reference and parentheses, clarifying why Option A is correct over Options C and D.", + "why_maybe_unnecessary": "Basic OOP tutorials often cover this, but for a 'zero knowledge' cheat sheet, this specific delegation is a common stumbling block.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:34:58Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:final-exam-study-guide-trial-python-basics-2023-q24", + "question_id": "final-exam-study-guide-trial-python-basics-2023-q24", + "exam_id": "final-exam-study-guide-trial-python-basics-2023", + "question_number": 24, + "status": "completed", + "question_snapshot": { + "topic": "9_OOP_Hard_2", + "question": "You have the following definitions for a class called Car:\n\nclass Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nYou want to create another class called Garage, which has two attributes that are initialized during object construction:\n- The 'capacity' attribute, which is an integer and must be passed to the object constructor.\n- The 'cars' attribute, which is an empty list.\n\nThe Garage class should also have two methods:\n1. The add_car() method, which adds Car objects to a Garage object. New Car objects can only be added if there is still capacity in the Garage object. If not, the method should return \"Capacity reached.\"\n2. The check_garage() method, which reports the Car objects that have been added to the Garage object. The method should return a dictionary in which the keys are the counts of Car objects starting from 1 and the values are the Car objects' descriptions.\n\nFor example, if we execute the following commands:\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n\nthe output should be:\n{1: 'Toyota, Camry', 2: 'Honda, Accord'}\n\nWhich of the following code segments achieve(s) what you want?", + "options": { + "a": "class Garage:\n def __init__(self, capacity, cars = []):\n self.capacity = capacity\n\n def add_car(self, car):\n self.cars += car if len(self.cars) < self.capacity else return 'Capacity reached.'\n\n def check_garage(self, car):\n return {index: car.get_description() for index, car in enumerate(self.cars, start=1)}", + "b": "class Garage:\n def __init__(self, capacity):\n self.capacity = capacity\n self.cars = []\n\n def add_car(self, car):\n if len(self.cars) < self.capacity:\n self.cars.append(car)\n else:\n return 'Capacity reached.'\n\n def check_garage(self):\n output = {}\n for index, car in enumerate(self.cars, start=1):\n output[index] = car.get_description()\n return output", + "c": "Both of the above will work.", + "d": "None of the above will work." + }, + "correct": "b", + "explanation": "Option B initializes capacity and an empty cars list, appends cars only when capacity remains, returns the required message when full, and builds the requested dictionary in check_garage().", + "code_context": "class Car:\n def __init__(self, brand, model):\n self.brand = brand\n self.model = model\n\n def get_description(self):\n return f\"{self.brand}, {self.model}\"\n\nmy_garage = Garage(2)\nmy_garage.add_car(Car(\"Toyota\", \"Camry\"))\nmy_garage.add_car(Car(\"Honda\", \"Accord\"))\nprint(my_garage.check_garage())\n# output:\n# {1: 'Toyota, Camry', 2: 'Honda, Accord'}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class." + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates adding methods with internal logic and attribute comparisons to a class, helping the student understand how add_car() and check_garage() should be structured." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary with integer keys starting from 1, which matches the expected output format of the check_garage() method." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "This snippet provides the fundamental syntax for defining a class and initializing multiple attributes in the __init__ constructor, which is the primary structure needed for the Garage class.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "Demonstrates adding methods with internal logic and attribute comparisons to a class, helping the student understand how add_car() and check_garage() should be structured.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows a dictionary with integer keys starting from 1, which matches the expected output format of the check_garage() method.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-2-w4-oop-fundamentals" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets cover class structure, method definitions, and the target dictionary format. However, they lack specific examples of using 'enumerate' with a 'start' parameter and the 'list.append()' method, making it difficult for a student with zero knowledge to confidently select Option B over the syntactically incorrect Option A.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The current snippets do not explain how to iterate with an index (enumerate) or how to properly add items to a list attribute (append).", + "missing_concepts": [ + "enumerate() with start parameter", + "list.append() method", + "list concatenation vs appending (+= vs .append)" + ], + "proposed_fix": "Add a snippet from Week 2 or Week 4 materials that explicitly shows list appending and the use of enumerate() to build a dictionary from a list." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet family 'Iteration and List Modification' featuring an example like: 'my_list = []; my_list.append(x); result = {i: val for i, val in enumerate(my_list, start=1)}'.", + "why_helpful": "This would directly address the two most specific technical requirements of the question: how to grow the list and how to generate the indexed dictionary.", + "why_maybe_unnecessary": "The student might infer list usage from prior general programming knowledge, but 'enumerate' is quite Python-specific.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:35:33Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + } + ] +} \ No newline at end of file diff --git a/data/vision_exam_pipeline/work_packets/evaluations/round2/introduction-to-python-trial-final-exam-solutions-py22.json b/data/vision_exam_pipeline/work_packets/evaluations/round2/introduction-to-python-trial-final-exam-solutions-py22.json new file mode 100644 index 0000000..c540c42 --- /dev/null +++ b/data/vision_exam_pipeline/work_packets/evaluations/round2/introduction-to-python-trial-final-exam-solutions-py22.json @@ -0,0 +1,8702 @@ +{ + "schema_version": "1.1", + "generated_at": "2026-03-24T10:43:09Z", + "round": "round2", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_count": 24, + "pending_question_ids": [], + "captured_pending_human_confirmation_ids": [], + "blocked_question_ids": [], + "questions": [ + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q01", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q01", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 1, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Logic_3", + "question": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?", + "options": { + "a": "if x in list(range(11))[::2]:\n print('Even number')\nelse:\n print('Odd number')", + "b": "if x % 2 != 0:\n print('Odd number')\nelse:\n print('Even number')", + "c": "if x in [1, 3, 5, 7, 9]:\n print('Odd number')\nelse:\n print('Even number')", + "d": "All of the programs work as intended." + }, + "correct": "d", + "explanation": "Option A checks membership in the even numbers from 0 through 10, option B checks oddness with modulo, and option C checks membership in the odd numbers from 1 through 9. All three correctly classify x as odd or even in the stated range.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the best general snippet as it explains list slicing with steps (e.g., [::2]), which is the most complex concept in Option A." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the best general snippet as it explains list slicing with steps (e.g., [::2]), which is the most complex concept in Option A." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Demonstrates the evaluation of boolean expressions and comparisons (True/False), which is necessary for understanding the logic in Options A, B, and C." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Provides the complete answer and explanation for the specific problem." + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "This piece contains the exact question text, all four options, and the correct answer explanation, providing a direct solution." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "rationale": "This is the best general snippet as it explains list slicing with steps (e.g., [::2]), which is the most complex concept in Option A.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Demonstrates the evaluation of boolean expressions and comparisons (True/False), which is necessary for understanding the logic in Options A, B, and C.", + "critical_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "rationale": "Provides the complete answer and explanation for the specific problem.", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-1-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam question is present in the candidate list. Without it, the student would lack information on the modulo operator (%) and the range() function behavior.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the identical question provides the answer, the general knowledge snippets are missing basic arithmetic operators and sequence generation functions.", + "missing_concepts": [ + "Modulo operator (%) for parity checking", + "range() function behavior (start, stop, step)", + "List membership operator ('in')" + ], + "proposed_fix": "Add a foundational snippet covering basic Python operators (arithmetic and comparison) and another explaining the range() function." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Basic Operators' that explains: 1. Modulo (%) for finding remainders/parity. 2. Comparison operators (==, !=). 3. The 'in' operator for checking membership in lists.", + "why_helpful": "This would allow a student to solve Option B and C from first principles rather than relying on an identical past exam match.", + "why_maybe_unnecessary": "Not needed if the student only cares about matching the specific question to the past exam bank.", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'Sequences with range()' explaining that range(n) produces numbers from 0 to n-1.", + "why_helpful": "Essential for understanding why range(11) includes the number 10, which is crucial for Option A.", + "why_maybe_unnecessary": "The identical question explanation already mentions the range 0 through 10.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:36:25Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you already have a variable called x, which contains a list of integers.\nWhich of the following programs will print you a list of the squared values of the elements in x?" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-13-w3-higher-order-patterns", + "snippet_label": "Higher-Order Patterns", + "week": 3, + "topic": "Higher-Order Patterns", + "pieces": [ + { + "item_id": "exam-midterm_2023-13-w3-higher-order-patterns", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "Suppose you have the following functions, one to elevates a number to square and the second elevates to cube:\ndef square(n):\nreturn (n**2)\ndef cube(n):\nreturn (n**3)\nYou want to apply both functions to the elements in a list at the same time.\nFor example:\nIf you have a list such " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q02", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q02", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 2, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Scope_2", + "question": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?", + "options": { + "a": "This code will produce an error because a is a global name that is referenced inside the local scope of inner().", + "b": "This code will not produce any error and will return 30.", + "c": "This code will produce an error because c is not defined before referencing.", + "d": "This code will not produce any error and will return 50." + }, + "correct": "b", + "explanation": "The function inner receives c as its argument, so c is defined. It can also read the global a. inner(5) returns 1 + 5 + 4 = 10, and outer returns 10 * 3 = 30.", + "code_context": "a = 1\ndef outer(b):\n b = 3\n def inner(c):\n d = 4\n return a + c + d\n return inner(5) * b\nouter(5)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "ks-2a6510492d", + "rationale": "Provides the fundamental rules of Python scope (global vs local) needed to solve the problem from first principles without relying on the exact past exam match." + }, + "top_three_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "Provides the fundamental rules of Python scope (global vs local) needed to solve the problem from first principles without relying on the exact past exam match." + }, + { + "item_id": "exam-extra_practice-2-w3-scope", + "rationale": "Demonstrates a concrete example of global and local variables with the same name, reinforcing the 'local dominates' and accessibility rules." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "ks-2a6510492d", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-2-w3-scope", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "rationale": "This piece contains the exact same question, code context, and explanation as the provided question JSON." + } + ], + "best_snippet_family": { + "snippet_id": "item:ks-2a6510492d", + "rationale": "Provides the fundamental rules of Python scope (global vs local) needed to solve the problem from first principles without relying on the exact past exam match.", + "critical_piece_ids": [ + "ks-2a6510492d" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "rationale": "Demonstrates a concrete example of global and local variables with the same name, reinforcing the 'local dominates' and accessibility rules.", + "critical_piece_ids": [ + "exam-extra_practice-2-w3-scope" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:ks-2a6510492d", + "rationale": "", + "needed_piece_ids": [ + "ks-2a6510492d" + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-2-w3-scope" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The lecture snippet explicitly states that global names are known everywhere except when a same-named local exists. This confirms 'a' is accessible. The code evaluation requires basic arithmetic (1+5+4=10, 10*3=30) which is straightforward once the scope error is debunked.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the scope rules are clear, a student might still be confused by nested function definitions or the exact syntax of returning a function call result.", + "missing_concepts": [ + "Nested function definition behavior", + "Function argument passing (c receives 5)" + ], + "proposed_fix": "Add a snippet or piece that explicitly shows a nested function accessing variables from the enclosing function's scope." + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:36:50Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Take a look at the following code segment. Will executing this code segment produce an error? If yes, then why?\na\nb\nc\nd\nb\nThe global variable 'a' is accessible inside the inner function without error. The code evaluates to inner(5) * 3 = (1 + 5 + 4) * 3 = 30." + } + ] + }, + { + "snippet_id": "item:ks-2a6510492d", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "ks-2a6510492d", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Global and local scope\nLocal names: defined inside a function (parameter names + any assignment inside). Only known inside the function. Global names: defined outside any function, known everywhere EXCEPT when a same-named local exists (local dominates). Python makes names local " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\nd\nThe variable 'result' is defined inside the scope of the 'power' function and is therefore a local variable. It cannot be accessed outside the function in the global scope." + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-15-w2-conditions", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-15-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\nA\nB\nC\nD\nA\nThe variable 'result' is defined inside the 'cube' function, making it local to that function. It cannot be accessed from the global scope." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Resit 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Executing the following program will produce an error. Why?\na\nb\nc\nd\na\nThe variable `result` is defined inside the `power` function, giving it local scope. It cannot be accessed outside the function in the global scope where `print(result)` is called." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "Calling the function func_1() will produce an error. Which line of the following code segment produces the error?\na\nb\nc\nd\na\nvar_1 is a local variable inside func_2, so it is not accessible in the scope of func_1. Furthermore, func_2 is never called, so var_1 is never created. The" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-6-w1-sequences-and-access", + "snippet_label": "Sequences and Access", + "week": 1, + "topic": "Sequences and Access", + "pieces": [ + { + "item_id": "exam-extra_practice-6-w1-sequences-and-access", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n\nWhich of the following lines of code will NOT create a list with the name subset, and the value [10, 8, 6, 4, 2]?\na\nb\nc\nd\nd\na: starts at -1 (10), step -2: [10,8,6,4,2]. Correct. b: [::-2] starts at last (10), step -2: [10,8,6,4,2]. Corre" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Take a look at the following class definition.\n\nSuppose that we create a Book object and call its add_review method three times, like this:\nbook_1 = Book(\"The Lightning Thief\", \"Rick Riordan\")\nbook_1.add_review(5)\nbook_1.add_review(3)\nbook_1.add_review(3)\n\nWhat will then the foll" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-2-w3-scope", + "snippet_label": "Scope", + "week": 3, + "topic": "Scope", + "pieces": [ + { + "item_id": "exam-extra_practice-2-w3-scope", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Scope", + "subtopic_title": "", + "search_text": "val = 2\ndef func():\n val = 3\n print(val)\nfunc()\nprint(val)\n\nWhich of the following code snippets produces the same output as the above code snippet?\na\nb\nc\nd\nc\nOriginal output: 3, 2. Option a: UnboundLocalError (val1 used before local assignment). Option b: global val2 modif" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q03", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q03", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 3, + "status": "completed", + "question_snapshot": { + "topic": "1_Basics_Variables_2", + "question": "What will be returned by the following code segment?", + "options": { + "a": "[0, None, 2, 3, None, 5, 6, 7, 8, None]", + "b": "[0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, 9]", + "c": "[None, 1.0, None, None, 3.5, None, None, None, None, '9']", + "d": "[0, None, 2, 3, None, 5, 6, 7, 8, 9]" + }, + "correct": "a", + "explanation": "The function appends each item if its exact type is int; otherwise it appends None. In the given list, 1.0, 3.50, and '9' are not ints, so those positions become None.", + "code_context": "def main(list_1):\n list_2 = []\n for item in list_1:\n if type(item) == int:\n list_2.append(item)\n else:\n list_2.append(None)\n return list_2\n\nmain([0, 1.0, 2, 3, 3.50, 5, 6, 7, 8, '9'])" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet provides a comprehensive breakdown of Python types, explicitly labeling 'abc' as str, 0 as int, and 123.456 as float, which is essential for distinguishing types in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet provides a comprehensive breakdown of Python types, explicitly labeling 'abc' as str, 0 as int, and 123.456 as float, which is essential for distinguishing types in the question." + }, + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Shows how the type() function is used inside a loop to compare elements against a specific type, paralleling the question's structure." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "This snippet contains the exact logic and values (1.0, 3.50, '9') used in the question, explicitly explaining that they are not 'int' and thus return 'None'." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "This snippet provides a comprehensive breakdown of Python types, explicitly labeling 'abc' as str, 0 as int, and 123.456 as float, which is essential for distinguishing types in the question.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "rationale": "Shows how the type() function is used inside a loop to compare elements against a specific type, paralleling the question's structure.", + "critical_piece_ids": [ + "exam-Resit 22/23-3-w3-return-behavior" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-3-w3-return-behavior" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The candidate list includes an identical past exam question. Even without it, the general type knowledge snippet would allow a student to identify which elements in the list are not integers.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "The coverage is excellent due to the presence of an identical question and high-quality general type definitions.", + "missing_concepts": [], + "proposed_fix": "" + }, + "suggested_changes": [], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:37:29Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-15-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-midterm_2024-15-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [1, 3, 5, 7, " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be returned by the following code segment?\na\nb\nc\nd\na\nThe function checks if the type is exactly int. 1.0, 3.50 are floats, and '9' is a string, so they are replaced by None." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-6-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-trial_midterm-6-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\ndef main(lst, condition=lambda x: x):\ny = []\nfor x in lst:\nif condition(x):\ny.append(x)\nreturn y\nWhat will this function return, when called in the following way:\nmain([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], lambda x: x % 2 != 0)\nA [2, 4, 6, 8, 10]\nB" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\na\nThe types of the elements are: 'abc' is str, 0 is int, None is NoneType, True is bool, 123.456 is float, 'False' is str (since it's in quotes), and {} is dict." + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-1-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-midterm_2024-1-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\na = True\nb = False\nc = True\nd = False\nif not (a or b) and (c or d):\nprint(\"True\")\nelse:\nprint(\"False\")\nWhat will be printed by the code?\nA True\nB False\nC The code will result in an error.\nD None" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q04", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q04", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 4, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - comprehension - 2", + "question": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II', 3: 'III', 4: 'IV', 5: 'V'}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "roman_nums = {num: roman for num, roman in zip(range(1, 6), ['I', 'II', 'III', 'IV', 'V'])}", + "b": "roman_nums = {roman: num for roman, num in zip(['I', 'II', 'III', 'IV', 'V'], range(1, 6))}", + "c": "roman_nums = {num: ['I', 'II', 'III', 'IV', 'V'][num] for num in range(1, 6)}", + "d": "roman_nums = {num: roman for num, roman in zip(range(1, 6), 'I II III IV V')}" + }, + "correct": "a", + "explanation": "Option A zips the integers 1 through 5 with the five Roman numeral strings and builds the required dictionary. The other options either reverse the keys and values, use incorrect indexing, or iterate over a plain string instead of the intended list of numerals.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here." + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows the scenario of creating a dictionary from two parallel lists (names and ages), which is the primary use case for the zip() function used in the correct answer." + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Another example of mapping keys to specific values (vowels to ASCII), helping the student recognize the pattern of building a mapping dictionary." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "This is the exact same question about creating the roman_nums dictionary using Roman numerals 1-5." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Describes a nearly identical task of creating a dictionary from a list (word_lengths) and explicitly mentions Option A as a valid dictionary comprehension, which reinforces the {key: value for ...} pattern required here.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "Shows the scenario of creating a dictionary from two parallel lists (names and ages), which is the primary use case for the zip() function used in the correct answer.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "rationale": "Another example of mapping keys to specific values (vowels to ASCII), helping the student recognize the pattern of building a mapping dictionary.", + "critical_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "While the near-identical snippet provides the answer directly, the remaining candidate snippets only describe the logic of mapping lists to dictionaries without showing the actual Python implementation (zip, range, or comprehension syntax) in the search text. A student with zero knowledge would find it difficult to distinguish between the correct zip() usage and the incorrect string iteration in Option D.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The candidate list is heavily reliant on past exam questions rather than syntax references. There is no piece explaining how zip() pairs items or that range(1, 6) excludes the number 6.", + "missing_concepts": [ + "zip() function mechanics (pairing elements from two iterables)", + "Dictionary comprehension syntax {k: v for ...}", + "range(start, stop) behavior (the stop value is exclusive)", + "Difference between iterating over a list vs. a space-separated string" + ], + "proposed_fix": "Add a general reference snippet for 'Dictionary Comprehensions' and 'Common Iteration Utilities' that explicitly shows the syntax and examples of zip() and range()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new 'Dictionary Comprehensions & Utilities' reference piece. It should define the syntax {key_expr: val_expr for item in iterable} and provide a clear example: `my_dict = {k: v for k, v in zip(['a', 'b'], [1, 2])}`. Also include a note that range(1, 6) produces numbers 1 to 5.", + "why_helpful": "This would bridge the gap from knowing 'what' needs to be done (mapping numbers to numerals) to 'how' it is written in Python, making the question answerable without relying on finding an identical past question.", + "why_maybe_unnecessary": "If the cheat sheet's primary purpose is to provide past exam answers, the near-identical piece already covers this specific question.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:38:02Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q05", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q05", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 5, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - manipulation - 2", + "question": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to only include the names that start with the letter 'A' or with the letter 'C'.\n\nSo executing the following command:\nprint(person_dict)\nshould give the following output:\n{'Alice': 25, 'Charlie': 35}\n\nWhich of the following code segments works as intended?", + "options": { + "a": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[name] = age", + "b": "person_dict = {}\nfor i, name in enumerate(names):\n if name[0] == 'A' or name[0] == 'C':\n person_dict[i] = ages[i]", + "c": "person_dict = {}\nfor name, age in zip(names, ages):\n if name[0] == 'A' or name[0] == 'C':\n person_dict.append(name:age)", + "d": "person_dict = {}\nfor i, name in enumerate(names):\n for j, letter in enumerate(name):\n if letter == 'A' or letter == 'C':\n person_dict[i] = ages[j]" + }, + "correct": "a", + "explanation": "Option A correctly iterates over names and ages together and stores only the names beginning with A or C as keys mapped to their ages. The other options use indices as keys, invalid dictionary syntax, or incorrect nested-loop logic.", + "code_context": "names = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Excluding the identical match, this is the best general snippet because it demonstrates creating a dictionary from a list where the keys are the list items and values are computed from them, matching the basic loop-and-assign pattern." + }, + "top_three_snippets": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Excluding the identical match, this is the best general snippet because it demonstrates creating a dictionary from a list where the keys are the list items and values are computed from them, matching the basic loop-and-assign pattern." + }, + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the fundamental syntax for creating a dictionary (roman_nums) and mapping keys to values using the bracket notation." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "This piece contains the exact same scenario (names and ages lists) and goal (person_dict with 'A' or 'C' filter) as the current question." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "Excluding the identical match, this is the best general snippet because it demonstrates creating a dictionary from a list where the keys are the list items and values are computed from them, matching the basic loop-and-assign pattern.", + "critical_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "rationale": "Shows the fundamental syntax for creating a dictionary (roman_nums) and mapping keys to values using the bracket notation.", + "critical_piece_ids": [ + "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-7-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The identical past exam piece provides the exact solution. Even without it, the Resit piece shows the dictionary assignment pattern d[key] = value, though the student would still need to figure out zip() and string indexing.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While dictionary assignment is covered, the specific use of zip() to iterate over two lists simultaneously is not explicitly explained in the general snippets provided.", + "missing_concepts": [ + "zip() function for parallel iteration", + "string indexing (e.g., name[0])" + ], + "proposed_fix": "Add a snippet or detail explaining how to use zip() to pair items from two lists for dictionary creation." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a 'Dictionary Construction from Lists' snippet that explicitly shows: 1. Initialization (d = {}), 2. zip(listA, listB) usage, 3. Conditional filtering, 4. Assignment (d[k] = v).", + "why_helpful": "This would allow a student to solve this question and similar 'convert two lists to a filtered map' problems without relying on finding a verbatim past exam question.", + "why_maybe_unnecessary": "The 'Resit 22/23-7' snippet already teaches the dictionary assignment pattern, which is the most critical syntax gap.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:38:22Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-1-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: \"name\" and \"mode\", which you want to be initialized at the time of object construction.\n\nThe \"name\" attribute can be any string, and it must be passed to the object constructor. The \"mode\" attribute is al" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q06", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q06", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 6, + "status": "completed", + "question_snapshot": { + "topic": "2-dictionaries - slicing - 2", + "question": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich of the following code segments works as intended?", + "options": { + "a": "max_rating = max(employee_ratings.values())\nfor employee, rating in employee_ratings.items():\n if rating == max_rating:\n print(employee)", + "b": "max_rating_employee = max(employee_ratings.keys())\nfor employee, rating in employee_ratings.items():\n if employee == max_rating_employee:\n print(employee)", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "a", + "explanation": "Option A correctly computes the maximum rating value and prints every employee whose rating matches it. Option B instead finds the maximum key lexicographically, not the employee with the highest rating.", + "code_context": "employee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This is the best general snippet as it demonstrates the exact pattern required: iterating over dictionary items using '.items()', checking a value condition (above average), and printing the corresponding keys (names)." + }, + "top_three_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This is the best general snippet as it demonstrates the exact pattern required: iterating over dictionary items using '.items()', checking a value condition (above average), and printing the corresponding keys (names)." + }, + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "rationale": "Mentions creating a dictionary with 'highest and low' keys, which reinforces the concept of looking for extremas in dictionary values." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "rationale": "This snippet contains the exact question text and context, including the employee_ratings dictionary and the goal of finding the highest performance rating." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "This is the best general snippet as it demonstrates the exact pattern required: iterating over dictionary items using '.items()', checking a value condition (above average), and printing the corresponding keys (names).", + "critical_piece_ids": [ + "exam-extra_practice-4-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "rationale": "Mentions creating a dictionary with 'highest and low' keys, which reinforces the concept of looking for extremas in dictionary values.", + "critical_piece_ids": [ + "exam-extra_practice-3-w2-dictionaries-and-mappings" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-4-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings" + ] + } + ], + "answerability": { + "status": "certain", + "confidence": "high", + "rationale": "The exact question is present in the near-identical pieces. Furthermore, the 'extra_practice-4' snippet provides a clear template for the iteration and conditional printing logic needed to evaluate the code options.", + "usable_without_prior_python_knowledge": true + }, + "gap_analysis": { + "summary": "While the logic of iteration is covered, there is no general snippet that explicitly explains the difference between 'dict.keys()' and 'dict.values()' or how 'max()' behaves when applied to them.", + "missing_concepts": [ + "dictionary.values() vs dictionary.keys()", + "max() behavior on dictionary views" + ], + "proposed_fix": "Add a conceptual snippet or piece that explains dictionary methods (.keys(), .values(), .items()) and their interaction with built-in functions like max()." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet titled 'Dictionary Methods and Max/Min' that shows: 1) d.keys() returns names, 2) d.values() returns scores/ratings, 3) max(d.values()) finds the highest score, while max(d.keys()) finds the 'alphabetically last' name.", + "why_helpful": "This would allow a student to solve the problem logically (comparing options A and B) even without seeing the exact past exam question.", + "why_maybe_unnecessary": "The 'extra_practice-4' snippet already shows the '.items()' iteration which is the core of the loop, and students might infer value-based maxing from the context.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:38:47Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-3-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-3-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Adelbrecht and Hortensia competed in a game. You have a dictionary with two subdictionaries:\n\nresults = {'Adelbrecht':{'attempt1':3,'attempt2':2,'attempt3':6},'Hortensia':{'attempt1':1,'attempt2':6}}\n\nYou would like to create a dictionary in which the keys are the highest and low" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-extra_practice-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "math_scores = {'John': 85, 'Sarah': 92, 'Michael': 78, 'Emma': 90, 'David': 82}\n\nYou want to find and print the names of the students who scored above the average score.\n\nWhich of the following code segments will work as intended?\na\nb\nc\nd\nb\nOption a has an indentation error (the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-midterm_2023-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nsample_dict = {\n\"name\": \"Kim\",\n\"age\": 25,\n\"birthdate\": \"3-2-1998\",\n\"city\": \"Amsterdam\"}\nSuppose you want to create a dictionary that only contains the keys 'name' and 'city'.\nWhich of the following code snippets return(s) the desired dic" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q07", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q07", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 7, + "status": "completed", + "question_snapshot": { + "topic": "2-list - comprehension - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "[2, 4]", + "b": "[3, 4, 5]", + "c": "[4]", + "d": "[]" + }, + "correct": "c", + "explanation": "The list comprehension keeps values x from [1, 2, 3, 4, 5] only when x is even and greater than 2. The only value satisfying both conditions is 4.", + "code_context": "numbers = [1, 2, 3, 4, 5]\nresult = [x for x in numbers if x % 2 == 0 and x > 2]\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension." + }, + "top_three_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension." + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Briefly mentions the logic of finding 'even numbers', which helps decode the `x % 2 == 0` part of the code segment." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "" + }, + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "rationale": "This piece is an exact match for the question, providing the same code logic (filtering even numbers > 2) and the correct output '4'." + } + ], + "best_snippet_family": { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "Provides an example of a loop that iterates through a list, checks a condition for each element, and returns a new filtered list, which is the conceptual foundation of a list comprehension.", + "critical_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "Briefly mentions the logic of finding 'even numbers', which helps decode the `x % 2 == 0` part of the code segment.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names" + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "Excluding the near-identical piece, there is no explanation of the specific Python 'list comprehension' syntax `[expression for item in iterable if condition]`. A student with zero knowledge would find the compact notation in the code context unintelligible based solely on the general snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets lack a definition or syntax guide for list comprehensions and the modulo operator.", + "missing_concepts": [ + "list comprehension syntax", + "modulo operator (%)", + "Python logical 'and' in comprehensions" + ], + "proposed_fix": "Add a general-purpose snippet explaining list comprehension structure and common filtering patterns (like even/odd checks)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a core concept snippet for 'List Comprehensions' that breaks down the syntax `[x for x in numbers if x > 2]` and explicitly defines `% 2 == 0` as the standard way to check for even numbers.", + "why_helpful": "This bridges the gap for a student who knows basic logic but doesn't recognize Python's specific shorthand for creating filtered lists.", + "why_maybe_unnecessary": "Students might learn this specific syntax through rote memorization of past exam answers if the question bank is small.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:39:23Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-6-w4-string-operations-and-methods", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "Suppose that you'd like to create a new DataFrame that contains only column 'B' for rows with indices 2, 4, and 6. Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nOption A uses a boolean mask on the index to find even numbers and specifies ['B'] as a list " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q08", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q08", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 8, + "status": "completed", + "question_snapshot": { + "topic": "2-list - manipulation - 1", + "question": "What is the output of the following code segment?", + "options": { + "a": "['a', 'bb', 'ccc']", + "b": "[1, 2, 3]", + "c": "[1, 'b', 3]", + "d": "['aa', 'bb', 'cc']" + }, + "correct": "a", + "explanation": "The loop iterates over pairs from zip(list1, list2) and multiplies each string by its matching integer, producing 'a', 'bb', and 'ccc'.", + "code_context": "list1 = [1, 2, 3]\nlist2 = ['a', 'b', 'c']\nresult = []\nfor item in zip(list1, list2):\n result.append(item[0] * item[1])\nprint(result)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code." + }, + { + "item_id": "aiq-2", + "rationale": "Provides examples of various list methods and operations, helping the student understand list-based logic, though it lacks the specific 'zip' and 'string multiplication' concepts." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "" + }, + { + "item_id": "aiq-2", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "Demonstrates the list append() method and basic list construction/printing, which covers the 'result = []', 'result.append()', and 'print(result)' parts of the code.", + "critical_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-2", + "rationale": "Provides examples of various list methods and operations, helping the student understand list-based logic, though it lacks the specific 'zip' and 'string multiplication' concepts.", + "critical_piece_ids": [ + "aiq-2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-16-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:aiq-2", + "rationale": "", + "needed_piece_ids": [ + "aiq-2" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While 'append' is covered, the core of the problem relies on two concepts completely missing from the candidates: 1) The zip() function pairing elements of lists together, and 2) String multiplication (e.g., 'a' * 2 = 'aa'). Without these, a student cannot determine the contents of the result list.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing definitions for 'zip' and the behavior of the multiplication operator between integers and strings.", + "missing_concepts": [ + "zip() function pairing", + "String-integer multiplication (repetition)", + "Tuple/item indexing inside a loop" + ], + "proposed_fix": "Add a new snippet explaining zip(listA, listB) and a note that 'abc' * 2 results in 'abcabc'." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for 'Zip and Pairing': 'zip(list1, list2) combines lists into pairs: e.g., zip([1, 2], ['a', 'b']) -> (1, 'a'), (2, 'b')'.", + "why_helpful": "Essential for decoding the 'for item in zip(...)' loop and accessing indices item[0] and item[1].", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + }, + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a snippet for 'String Multiplication': 'Multiplying a string by an integer repeats it: \"a\" * 3 -> \"aaa\"'.", + "why_helpful": "Required to understand the calculation 'item[0] * item[1]' where one is an int and the other a string.", + "why_maybe_unnecessary": "", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:39:51Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-16-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-midterm_2023-16-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Consider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylist.count(3))\nWhat will be the output?\nHint: The remove() list method removes the first occurrence of the element with the specified value.\nA 3\nB 4\nC " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-7-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-7-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "What is the output of the following code segment?\na\nb\nc\nd\nc\nThe list comprehension filters numbers that are even (x % 2 == 0) and greater than 2 (x > 2). From the list, only 4 satisfies both conditions." + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-10-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-10-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nx = {1: 10, 2: 20, 3: 30, 4: 40}\nWhat will the following line of code print?\nprint(list(x.values()) + list(x.keys()))\nA This code will result in an error because you cannot concatenate two lists using the + operator.\nB [10, 20, 30, 40, 1" + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "What is the result of {int(x) * 2 for x in '01212' if x in '02'}?\nSets only store unique values. 0*2=0 and 2*2=4. Repeated values are ignored.\nComprehensions" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "def multiply(num1, num2):\nmultiply() has no return statement, so it returns None. print(multiply(2,3)) prints None. But inside, global result is set to 6. print(result) prints 6. Output: None, 6.\nExam • extra_practice • Q7" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-3-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-Resit 22/23-3-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe function checks if the type of each element `i` in the list `x` is the same as the type of `x` (which is a list). The only element in `x` that is a list is `[]`. So, it appends `[]` to `y`, resulting in `[[]]`." + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "What will be printed by the following code segment?\na\nb\nc\nd\nb\nThe type of x is a list. The loop checks if the type of each element is equal to the type of x. The only element in x that is a list is the empty list `[]`. Thus, `[[]]` is returned." + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q09", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q09", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 9, + "status": "completed", + "question_snapshot": { + "topic": "2-list - slicing - 1", + "question": "Suppose you have a list called mylist. You want to extract every fourth element starting from index 2 (inclusive) to the second-to-last index (inclusive) of that list using the following line of code:\nsubset = mylist[___:___:___]\n\nFor example, if you have:\nmylist = [10, 15, 20, 25, 30, 35, 40, 45, 50]\n\nthen executing the following command:\nprint(subset)\n\nshould print:\n[20, 35]\n\nWhat should the blanks be filled with?", + "options": { + "a": "2:-1:3", + "b": "2:len(mylist)-1:3", + "c": "Both of the given options are correct.", + "d": "None of the given options are correct." + }, + "correct": "c", + "explanation": "Both stop values exclude the last element while starting at index 2 and stepping by 3, so both expressions return [20, 35] for the example list.", + "code_context": "subset = mylist[___:___:___]" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question." + }, + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Mentions operations on a 'list called x', which provides some context for list-based exam questions, though it does not cover slicing." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "This is the only snippet that demonstrates the triple-parameter slicing syntax `[start:stop:step]`, which is the core concept of the question.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "rationale": "Mentions operations on a 'list called x', which provides some context for list-based exam questions, though it does not cover slicing.", + "critical_piece_ids": [ + "exam-Resit 22/23-5-w1-functions-and-imports" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "While one snippet shows the `[start:stop:step]` syntax, it does not explain that the 'stop' index is exclusive, nor does it explain negative indexing (e.g., `-1`) or the `len()` function's role in indexing. A student with zero prior knowledge could not distinguish between options (a), (b), and (c) based on these snippets alone.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The available snippets show the slicing syntax but omit the semantic rules required to solve the problem.", + "missing_concepts": [ + "exclusive stop index in slicing", + "negative indexing (specifically -1 as the last element)", + "relationship between len(list) and the last index", + "slicing step logic (Nth element vs step N-1)" + ], + "proposed_fix": "Add a foundational snippet about Python list slicing that explicitly defines the inclusive start, exclusive stop, and the behavior of the step parameter, including negative indices." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a snippet titled 'List Slicing Fundamentals' that explains `my_list[start:stop:step]`. It should state: 1) 'start' is the first index included. 2) 'stop' is the index where the slice ends (the element at 'stop' is NOT included). 3) '-1' refers to the last element. 4) 'len(my_list)' is the total count, so 'len(my_list)-1' is the index of the last element.", + "why_helpful": "This would directly allow a student to evaluate why both `-1` and `len(mylist)-1` effectively exclude the last element and satisfy the 'second-to-last index inclusive' requirement.", + "why_maybe_unnecessary": "If the student already understands standard range-based indexing from other languages, they might guess, but Python's negative indexing is unique enough to require a snippet.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:40:37Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q10", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q10", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 10, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Argument_2", + "question": "Suppose you have the following function, which takes a list of integers as an argument:\n\nWhat will be returned, if we call the function as follows:\nmain([0, 1, 2, 23, 24, 25])", + "options": { + "a": "'abcxyz'", + "b": "['a', 'b', 'c', 'x', 'y', 'z']", + "c": "'012232425'", + "d": "None of the given options." + }, + "correct": "a", + "explanation": "The function walks through the alphabet with enumerate and appends each character whose index is present in the input list, giving a, b, c, x, y, and z.", + "code_context": "def main(x):\n alphabet = 'abcdefghijklmnopqrstuvwxyz'\n y = ''\n for index, character in enumerate(alphabet):\n if index in x:\n y += character\n return y" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic." + }, + "top_three_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic." + }, + { + "item_id": "aiq-4", + "rationale": "Contains pieces on 'Return Behavior', which is essential for understanding that the function results in a single value rather than a side effect like printing." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Establishes the context of the alphabet string." + }, + { + "item_id": "aiq-4", + "rationale": "Explains foundational return value mechanics." + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Mentions the exact 'alphabet' string variable used in the question, which helps a zero-knowledge student recognize the data structure being iterated over, even though it doesn't explain the loop logic.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "Contains pieces on 'Return Behavior', which is essential for understanding that the function results in a single value rather than a side effect like printing.", + "critical_piece_ids": [ + "aiq-4" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Establishes the context of the alphabet string.", + "needed_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + }, + { + "snippet_id": "item:aiq-4", + "rationale": "Explains foundational return value mechanics.", + "needed_piece_ids": [ + "aiq-4" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The question's solution relies entirely on knowing that 'enumerate(alphabet)' yields pairs of (index, character). Without a snippet explaining that 'index' represents the numeric position (starting at 0), a student with zero prior knowledge cannot definitively solve the problem, as they wouldn't know if 'index' refers to the position or something else.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "There is no explanation of the 'enumerate' function or the concept of retrieving an index during a loop iteration.", + "missing_concepts": [ + "enumerate() function", + "unpacking (index, value) in for loops", + "zero-based indexing" + ], + "proposed_fix": "Add a snippet explaining 'enumerate(sequence)': 'The enumerate() function allows you to loop through a sequence and have an automatic counter (index). Example: for i, val in enumerate([\"A\", \"B\"]): yields (0, \"A\") then (1, \"B\").'" + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a new snippet for the 'enumerate' function: 'The enumerate() function adds a counter to an iterable and returns it in a form of enumerate object. This object can then be used directly in for loops to get both the index and the value of each item. Example: for index, value in enumerate(\"cat\"): index 0 is \"c\", 1 is \"a\", 2 is \"t\".'", + "why_helpful": "This provides the missing technical link needed to interpret the loop in the question correctly.", + "why_maybe_unnecessary": "A student might guess that 'index' means position, but 'enumerate' is a specific Python keyword that needs explicit definition for zero-knowledge users.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:41:48Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 19, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2024-18-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2024-18-w2-loops", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-15-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-15-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "additional", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function count_characters, which takes two arguments:\na list of strings which are names, and\nan optional keyword argument called character that has a default value of 'a'.\ndef count_character(x, character='a'):\ny = {}\nfor key in x:\ncount = 0\nfor cha" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-4-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\n\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\nb\nThe function uses y=11 as a default argument. The while loop runs while i < 11 (from 1 to 10) and appends formatted string" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-9-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2023-9-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef add_numbers(num1, num2 = 10, num3 = 20):\nreturn num1 + num2 + num3\nWhat are the outputs if we call the function three times as follows:\nadd_numbers(5, 15)\nadd_numbers(5, num3 = 30)\nadd_numbers(num2 = 15, num3 = 10)\nA 40\n45\n25\nB " + } + ] + }, + { + "snippet_id": "item:exam-midterm_2024-14-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-midterm_2024-14-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial_midterm-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nWhich of the following functions will return the same values as the function above, if we call the function thrice as follows:\nmultiply(1, 2, fact" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q11", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q11", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 11, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Built-in_1", + "question": "Suppose you have a variable called x which contains a string as follows:\n\nx = 'Hello world'\n\nWhich of the following lines of code produce(s) 2 as an output?", + "options": { + "a": "print(x.count('o'))", + "b": "print(x.split(' ')[0].count('ll'))", + "c": "print(len(x)//5)", + "d": "All of the given options." + }, + "correct": "d", + "explanation": "The rendered solution page marks option D, indicating that the exam intends all three listed expressions to produce 2 for the given value of x.", + "code_context": "x = 'Hello world'" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question." + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Shows a multiple-choice question structure where several expressions evaluate to the same result (True), leading to 'all lines' being correct, similar to the logic in the current question's Option D." + }, + { + "item_id": "exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of string slicing and list conversion, which familiarizes the student with string-to-sequence operations like the .split() method in the question." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "" + }, + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "This snippet illustrates the conceptual logic for counting characters in a string (iterating and incrementing a count), which provides a foundation for understanding the purpose of the .count() method used in the question.", + "critical_piece_ids": [ + "exam-trial_midterm-19-w2-dictionaries-and-mappings" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "Shows a multiple-choice question structure where several expressions evaluate to the same result (True), leading to 'all lines' being correct, similar to the logic in the current question's Option D.", + "critical_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "rationale": "Provides an example of string slicing and list conversion, which familiarizes the student with string-to-sequence operations like the .split() method in the question.", + "critical_piece_ids": [ + "exam-midterm_2023-14-w2-loops" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "rationale": "", + "needed_piece_ids": [ + "exam-trial_midterm-19-w2-dictionaries-and-mappings" + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "rationale": "", + "needed_piece_ids": [ + "exam-Resit 22/23-1-w2-lists-and-sets" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "The candidate snippets are all past exam questions rather than documentation. None of them define the specific methods (.count, .split), the built-in function (len), or the floor division operator (//) required to verify the arithmetic in the options. A student with zero prior knowledge could not conclude that len('Hello world') // 5 equals 2 without knowing what len or // do.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets fail to provide definitions for core string methods and basic Python operators used in the question.", + "missing_concepts": [ + "str.count()", + "str.split()", + "len() function", + "// (floor division operator)" + ], + "proposed_fix": "Add a foundational card covering 'Basic String Methods and Operators' that explicitly defines len(), .count(), .split(), and arithmetic operators like // and %." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a card titled 'Strings & Arithmetic Basics' including: 1. len(x): returns number of characters. 2. x.count('a'): returns occurrences of 'a'. 3. x.split(' '): breaks string into a list by space. 4. a // b: floor division (e.g., 11 // 5 = 2).", + "why_helpful": "This directly enables a student with zero knowledge to calculate the values for options A, B, and C.", + "why_maybe_unnecessary": "If the goal is only to provide past exam context, but in that case, the student remains unable to solve this specific problem.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:42:33Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have a variable called x which contains an integer between 0 and 10 (both are inclusive).\n\nWhich of the following programs will tell you whether x contains an odd or even number?\na\nb\nc\nd\nd\nAll three programs correctly identify whether x is odd or even for integers bet" + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-19-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-19-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\ndef my_count_function(string):\ncounts = {}\nfor letter in string:\nif letter in counts:\ncounts[letter] += 1\nelse:\ncounts[letter] = 1\nreturn counts\nAnd you create the following two dictionaries:\napple_count = my_count_function(\"apple\")\npeach_" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-4-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-4-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "Suppose you have the following function, which takes two integers as arguments:\nWhat will be printed by the following line of code:\nprint(main(1))\na\nb\nc\nd\na\nThe function `main` is called with `x=1`. `y` defaults to 11. The `while` loop runs while `i < 11`, which means it will run" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-5-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x, where:\n\nWhich of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A creates a set (removing duplicates) and sorts it in reverse order, yielding [5, 4, 3, 2, 1]. Option B uses slicing to step backwards by" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q12", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q12", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 12, + "status": "completed", + "question_snapshot": { + "topic": "3_Function_Flexible-Argument_2", + "question": "You need to write a function called main which accepts a list of integers as an argument. The function should return a tuple of two integers, in which the first is the sum of the squares of all even numbers, and the second is the sum of the squares of all odd numbers.\n\nFor example, calling the function as:\nmain(1, 2, 3, 4)\nshould return:\n(20, 10)\n\nWhich of the following blocks of code fits with the rest of the program and will you give the intended output?", + "options": { + "a": "for i in args:\n if i % 2 == 0:\n total_even += i**2\n else:\n total_odd += i**2\n\nreturn (total_even, total_odd)", + "b": "for i in args:\n if i % 2 == 1:\n total_even += i\n else:\n total_odd += i\n\nreturn (total_even**2, total_odd**2)", + "c": "for i in args:\n if i % 2 == 0:\n total_even.append(i**2)\n else:\n total_odd.append(i**2)\n\nreturn (sum(total_even), sum(total_odd))", + "d": "All of the given code blocks work as intended." + }, + "correct": "a", + "explanation": "Option A directly accumulates the squares of even numbers and odd numbers into the two totals and returns them as the required tuple.", + "code_context": "def main(*args):\n total_even = 0\n total_odd = 0\n\n # missing lines\n # ..." + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "aiq-4", + "rationale": "The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question." + }, + "top_three_snippets": [ + { + "item_id": "aiq-4", + "rationale": "The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question." + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "Specifically mentions a function (sum_even_integers) that accepts flexible arguments and performs parity filtering, directly mapping to the question's logic." + }, + { + "item_id": "aiq-5", + "rationale": "Contains a reminder about tuple syntax, helping the student recognize that (total_even, total_odd) is a valid tuple return." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "aiq-4", + "rationale": "" + }, + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "rationale": "" + }, + { + "item_id": "aiq-5", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:aiq-4", + "rationale": "The 'multiply(*args)' example clearly demonstrates how to iterate over a flexible number of arguments using a for-loop and return a calculated result, which is the core structure needed for this question.", + "critical_piece_ids": [ + "aiq-4" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "Specifically mentions a function (sum_even_integers) that accepts flexible arguments and performs parity filtering, directly mapping to the question's logic.", + "critical_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:aiq-5", + "rationale": "Contains a reminder about tuple syntax, helping the student recognize that (total_even, total_odd) is a valid tuple return.", + "critical_piece_ids": [ + "aiq-5" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:aiq-4", + "rationale": "", + "needed_piece_ids": [ + "aiq-4" + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "rationale": "", + "needed_piece_ids": [ + "exam-extra_practice-9-w3-return-behavior" + ] + }, + { + "snippet_id": "item:aiq-5", + "rationale": "", + "needed_piece_ids": [ + "aiq-5" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "medium", + "rationale": "The snippets provide the framework for flexible arguments (*args), iteration, and tuple returns. However, the student still needs to know the specific syntax for modulo (%) to check even/odd status and exponentiation (**) for squaring, which are not explicitly in these snippets.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "Missing explicit demonstration of basic Python arithmetic operators for parity checks and power calculations.", + "missing_concepts": [ + "modulo operator (%) for parity checks", + "exponentiation operator (**) for squaring" + ], + "proposed_fix": "Add a snippet or key point covering arithmetic operators, specifically highlighting how to use % 2 to identify even/odd numbers and ** 2 to square values." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Python Arithmetic Operators: Use `n % 2 == 0` to check if a number is even, and `n % 2 != 0` for odd. Use `n ** 2` to calculate the square of n.", + "why_helpful": "These operators are essential for the logic required in Option A but are not covered in the provided high-level function snippets.", + "why_maybe_unnecessary": "Students might have these concepts from earlier foundational weeks (Week 1 math) not represented in this subset.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:43:04Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 34, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-extra_practice-9-w3-return-behavior", + "snippet_label": "Return Behavior", + "week": 3, + "topic": "Return Behavior", + "pieces": [ + { + "item_id": "exam-extra_practice-9-w3-return-behavior", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Assume sum_even_in_list(l1) filters non-integers and sums even integers.\n\nYou want sum_even_integers that accepts a flexible number of arguments.\n\nFor example: sum_even_integers(1,'2', 3.0, 4) should return 4.\n\nWhich of the following function definitions will work as intended?\na\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Resit 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4.4" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "snippet_label": "Arguments", + "week": 3, + "topic": "Arguments", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-6-w3-arguments", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called main which accepts a flexible number of keyword arguments. The function should compute and return the sum of the values of the arguments.\n\nFor example, if you call the function as:\nmain(apple=1.99, banana=0.99, orange=1.49)\nit should return:\n4." + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:aiq-2", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "You need to write a function called sort_list that accepts a list of integers.\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q11\nFor example:\nIf we call the function as:\nsort_list([-9, 2, 5, -3, -10, 4, 7])\n" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "List method effects and resulting list\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q16\nConsider the following code snippet:\nmylist = [1, 3, 2, 3, 4, 5, 3, 3]\nmylist.append('3')\nmylist.remove(3)\nprint(mylis" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Why does the following code work even though strings are immutable?\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nImmutability/names" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "If df.A has 3 elements, which operation will raise a ValueError?\nWhen broadcasting a collection to a Series, the shapes must match. (3,) and (2,) cannot be broadcast together.\nBroadcasting Errors" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "What does the slice s[::-2] do for the string s = 'abcdef'?\nThe step -2 reverses the string and skips every second character, starting from the end ('f', then 'd', then 'b').\nString Slicing" + }, + { + "item_id": "aiq-2", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Sequences and Access", + "subtopic_title": "", + "search_text": "Slicing negative step\nRead the slice as `start:stop:step`; with a negative step Python walks right-to-left and still excludes the stop position.\nSlicing negative step" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "subtopic:w1-functions-and-imports:w1-functions-and-imports-core", + "snippet_label": "Built-ins Intro, Functions, and Modules", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ai-example-8", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Income tax branches and return shape\nSuppose your country imposes the following tax brackets:\nBracket Tax Taxable income\nrate Over Not over\n1 10% $0 $11,000\n2 12% $11,000 $45,000\n3 22% $45,000 $95" + }, + { + "item_id": "kp-2", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Use `print(...)` to display a value. A function groups reusable code and may also return a value to its caller." + }, + { + "item_id": "ai-example-3", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "from-import binds only the imported name\nclear_names()\n\nimport extension\nimport extension as ex\ntry:\n print(ex.YEAR)\nexcept Exception as e:\n print(e)\n\ntry:\n print(extension.YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually available after `im" + }, + { + "item_id": "ai-example-4", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Aliased from-import uses the alias locally\nclear_names()\n\nfrom extension import create_absolute_year\ntry:\n print(create_absolute_year(1))\nexcept Exception as e:\n print(e)\n\ntry:\n print(YEAR)\nexcept Exception as e:\n print(e)\nKeep track of which name is actually availabl" + }, + { + "item_id": "kp-1", + "item_type": "key_point", + "bucket": "keyPoints", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "`import x` keeps the module name, `import x as y` renames it, and `from x import z` brings `z` into scope directly." + }, + { + "item_id": "ai-example-1", + "item_type": "ai_example", + "bucket": "aiExamples", + "topic": "Functions and Imports", + "subtopic_title": "Built-ins Intro, Functions, and Modules", + "search_text": "Import module under its original name\nimport numpy\nnumpy.random.randint(1, 10) # works\n\nimport numpy as np\nnp.random.randint(1, 10) # works\nnumpy.random.randint(1, 10) # ERROR\n\nfrom numpy.random import randint\nrandint(1, 10) # works\n\nfrom numpy.random import r" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:aiq-4", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You need to write a function called print_info which takes two required arguments called name and age, and a flexible number of keyword\nCheck whether the method mutates the list in place and what the list looks like after each call.\nExam • midterm_2023 • Q10\nFor example:\nIf we ca" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you have the following function:\nTrace the returned value, not just what gets printed while the function runs.\nExam • trial_midterm • Q3\nSuppose you have the following function:\ndef multiply(*args, factor=2):\ntotal = 1\nfor num in args:\ntotal *= num\nreturn total * factor\nW" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Comprehensions", + "subtopic_title": "", + "search_text": "Mutable default argument\ndef f(lst=[]): — the [] is created ONCE at def time and persists across calls. Fix: use None and create inside function" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Implicit return None\nFunction without return statement, or where return is not reached, returns None. print(func()) will print None." + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Unordered collections equality\n{1:1,2:2}=={2:2,1:1} is True; {1,2}=={2,1} is True; [1,2]==[2,1] is False" + }, + { + "item_id": "aiq-4", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Working With Values", + "subtopic_title": "", + "search_text": "1 + True = 2 (bool is subclass of int)\nTrue==1, False==0 in numeric contexts. type(True)==int is False but isinstance(True,int) is True" + } + ] + }, + { + "snippet_id": "item:aiq-5", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Arguments", + "subtopic_title": "", + "search_text": "You have to write a function called summarize which take a list of integers as an argument.\nReturn `{'amount': len(nums), 'smallest': min(nums), 'largest': max(nums), 'total': sum(nums)}`.\nExam • midterm_2024 • Q13\nThe function should return a dictionary with the following key-va" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Assume you have the following variables:\nDecide whether the code is rebinding a name or mutating a shared mutable object.\nExam • trial_midterm • Q4\nAssume you have the following variables:\nx = 3\ny = 3.0\nz = '3'\nWhat will be printed by the following code:\nprint((x != z and x == in" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "UnboundLocalError\nIf a name appears on the left side of assignment ANYWHERE in a function, Python treats it as local THROUGHOUT the function body — even before the assignment line" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Return Behavior", + "subtopic_title": "", + "search_text": "Single-element tuple needs trailing comma\n(1) is int, not tuple. (1,) or 1, is a tuple" + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "Higher-Order Patterns", + "subtopic_title": "", + "search_text": "map/filter return iterables, not lists\nlist(map(lambda x: x*2, l)) — must wrap in list(). Without it: " + }, + { + "item_id": "aiq-5", + "item_type": "ai_common_question", + "bucket": "aiQuestions", + "topic": "String Operations and Methods", + "subtopic_title": "", + "search_text": "Slicing creates a NEW object\nl2=l1 vs l2=l1[:] — l2=l1 shares the SAME object, slicing creates independent copy" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q13", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q13", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 13, + "status": "completed", + "question_snapshot": { + "topic": "6-string - fstring - 1", + "question": "You have the following objects loaded in Python:\nname = \"Alice\"\nage = 25\ncountry = \"the USA\"\n\nYou need to print the following string:\nMy name is Alice. I am 25 years old, and I am from the USA.\n\nWhich of the following lines of code works as intended?", + "options": { + "a": "message = \"My name is {0}. I am {2} years old, and I am from {1}.\".format(name, country, age)\nprint(message)", + "b": "message = f\"My name is {name}. I am {age} years old, and I am from {country}.\"\nprint(message)", + "c": "message = 'My name is ' + name + '. I am ' + str(age) + ' years old, and I am from ' + str(country) + '.'\nprint(message)", + "d": "All of the given options are correct." + }, + "correct": "d", + "explanation": "All three code variants produce the target sentence: one uses format, one uses an f-string, and one uses string concatenation with str(age) and str(country).", + "code_context": "name = \"Alice\"\nage = 25\ncountry = \"the USA\"" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "This snippet establishes that names are strings, which helps a student identify the data types being manipulated in the question, though it doesn't help with the formatting syntax." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "This snippet mentions the concept of 'formatting' strings (specifically phone numbers), which is the closest thematic match to the question, even though the truncated text does not provide the specific syntax needed to solve it.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "This snippet establishes that names are strings, which helps a student identify the data types being manipulated in the question, though it doesn't help with the formatting syntax.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-3-w1-objects-and-names" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the candidate snippets demonstrate the syntax for f-strings, the .format() method, or string concatenation with type conversion (str()). The snippets are almost entirely focused on dictionaries and data structures (Week 2), while this question tests Week 1 string formatting fundamentals.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippet database is missing fundamental content on string formatting and manipulation.", + "missing_concepts": [ + "f-strings (syntax: f'...')", + "str.format() method (including positional indices like {0}, {1})", + "string concatenation (+) and the requirement to use str() for non-string objects" + ], + "proposed_fix": "Add a dedicated snippet family for 'String Formatting' that explicitly shows examples of f-strings, .format(), and concatenation side-by-side." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Create a new snippet: 'Python String Formatting Methods'. It should include: 1. f-strings: f\"My name is {name}\"; 2. .format(): \"My name is {0}\".format(name); 3. Concatenation: \"My name is \" + name + \" and I am \" + str(age) + \" years old\".", + "why_helpful": "This would directly allow a student with zero knowledge to compare the options in the question to the provided syntax examples.", + "why_maybe_unnecessary": "Only unnecessary if such a snippet already exists under a different topic that wasn't included in the candidates.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:44:35Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the performance ratings of employees in a company:\nemployee_ratings = {'John': 8, 'Sarah': 9, 'Michael': 7, 'Emma': 9, 'David': 6}\n\nYou need to find and print the name of the employee(s) with the highest performance rating.\n\nWhich" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-6-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have the following dictionary that represents the monthly sales of a store:\nmonthly_sales = {'January': 1500, 'February': 2200, 'March': 1800, 'April': 2400, 'May': 2000, 'June': 2800}\n\nYou need to calculate the average sales for the first three months (January, February, and" + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You would like to write a function called get_tld that extracts the top-level domain from the URL of a website. The function takes the URL as the input string in the following format:\n\"https://www.[SECOND-LEVEL DOMAIN].[TOP-LEVEL DOMAIN]/[FOLDER 1]/[...]/[FOLDER N]/[PAGE NAME].ht" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-1-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "You'd like to define a class called Vehicle. It should have two attributes: name and mode, which you want to be initialized during object creation. The name attribute can be any string, and it must be passed to the object during creation. The mode attribute is also a string, but " + } + ] + }, + { + "snippet_id": "item:exam-trial_midterm-8-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial_midterm-8-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have the following dictionary:\nlibrary = {\"books\": 5,\n\"genres\": ['action', 'romance', 'thriller', 'classics']}\nYou want to:\n- add a key \"years\", of which the value is a list of strings that are the years of publication, i.e., [\"1932\" , \"2012\", \"1899\",\n\"2000\", \"1984\"]," + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-5-w1-functions-and-imports", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "exam-Resit 22/23-5-w1-functions-and-imports", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "Suppose you have a list called x. Which of the following code segments will print the following list?\n[5, 4, 3, 2, 1]\na\nb\nc\nd\nc\nOption A extracts unique elements with `set(x)`, resulting in `{1, 2, 3, 4, 5}`, then sorts them in reverse order, giving `[5, 4, 3, 2, 1]`. Option B us" + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q14", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q14", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 14, + "status": "completed", + "question_snapshot": { + "topic": "7-pandas - easy - 2", + "question": "Suppose you have the following DataFrame called df, and assume that pandas is already imported:\n\n Player Goals Assists\n0 John 5 2\n1 Jane 3 6\n2 Alex 2 4\n\nAll of the following lines of code make the same selection, but one of the results has a different datatype. Which one?", + "options": { + "a": "df.loc[:, 'Goals']", + "b": "df['Goals']", + "c": "df.loc[[0, 1, 2], 'Goals']", + "d": "df.loc[:, ['Goals']]" + }, + "correct": "d", + "explanation": "The first three expressions return a Series, while selecting with a list of column names returns a one-column DataFrame instead.", + "code_context": "" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details." + }, + "top_three_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details." + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows a standard DataFrame with columns 'A' and 'B', helping the student visualize the structure mentioned in the question." + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions a 'pandas Series', which is one of the datatypes involved in the question options." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "" + }, + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "" + }, + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "This snippet is the only one that explicitly mentions 'Inspecting and Selecting Data' in the topic/label, although the preview text is cut off and doesn't show the selection syntax details.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "Shows a standard DataFrame with columns 'A' and 'B', helping the student visualize the structure mentioned in the question.", + "critical_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "Mentions a 'pandas Series', which is one of the datatypes involved in the question options.", + "critical_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data" + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures" + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "rationale": "", + "needed_piece_ids": [ + "exam-Test Exam 07-06-22-5-w5-pandas-core-structures" + ] + } + ], + "answerability": { + "status": "insufficient", + "confidence": "low", + "rationale": "None of the provided snippets explain the crucial difference between selecting a column as a scalar (returning a Series) vs. selecting with a list (returning a DataFrame). The snippets show DataFrame usage but not the specific syntax/datatype rules required to answer 'Which one has a different datatype?'.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The snippets identify pandas structures but fail to provide the rules for selection return types.", + "missing_concepts": [ + "Difference between Series and DataFrame return types in pandas selection", + "Behavior of .loc when passed a single label vs a list of labels", + "The use of double brackets [[]] vs single brackets [] for column selection" + ], + "proposed_fix": "Add a summary item or a detailed lecture snippet that explicitly states: 'Selecting with a single label (df['A'] or df.loc[:, 'A']) returns a Series, while selecting with a list of labels (df[['A']] or df.loc[:, ['A']]) returns a DataFrame.'" + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a key point or cheat sheet item: 'Pandas Selection Types: df['col'] or df.loc[:, 'col'] returns a Series (1D). df[['col']] or df.loc[:, ['col']] returns a DataFrame (2D). Passing a list to .loc always forces a DataFrame result even for a single column.'", + "why_helpful": "This directly addresses the 'different datatype' logic required by the question.", + "why_maybe_unnecessary": "If the user only wants past exam questions as snippets, this would need to be synthesized from a lecture.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:45:20Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "snippet_label": "Inspecting and Selecting Data", + "week": 5, + "topic": "Inspecting and Selecting Data", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-6-w5-inspecting-and-selecting-data", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Inspecting and Selecting Data", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df that looks like this, when printed:\n\n A B C D\n1 9.1 9.5 9.0 6.0\n2 6.4 8.2 7.5 1.7\n3 2.5 5.3 8.8 3.0\n4 6.7 3.6 7.2 6.9\n5 8.4 1.9 8.2 3.3\n6 8.1 8.4 9.9 2.2\n\nSuppose that you'd like to create a new DataFrame" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "snippet_label": "OOP Fundamentals", + "week": 4, + "topic": "OOP Fundamentals", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-2-w4-oop-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "OOP Fundamentals", + "subtopic_title": "", + "search_text": "Suppose that you also want to write a method called compare that compares the book to another book and gives a recommendation for which one to read. A book is better than another book if its average review score is higher than the second book's and it has at least as many reviews" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-5-w4-string-fundamentals", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df with columns \"A\" and \"B\". You'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\nA\nB\nC\nD\nA\nVectorized addition in Pandas is perform" + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w2-conditions", + "snippet_label": "Conditions", + "week": 2, + "topic": "Conditions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w2-conditions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Conditions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You're trying to write a function called is_anagram, which takes two strings as inputs and checks whether they are anagrams of each other. That is: whether one of them can be written by rearranging the letters of the other. Upper case and lower case versions of a letter count as " + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-3-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries.\n\nEach dictionary in the students list has two keys: \"Name\" and \"Grade\". The corresponding values are student names (as strings) and course grades (as floats).\n\nFor each student, you'd li" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas DataFrame called df. It has a column called \"A\" and a column called \"B\". Both contain numbers.\n\nYou'd like to create a column called \"C\", which contains the sum of the numbers in columns \"A\" and \"B\". Which of the following code lines will achieve what you want?\n" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Resit 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples. Which of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True). Therefore, all lines print True." + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "snippet_label": "Lists and Sets", + "week": 2, + "topic": "Lists and Sets", + "pieces": [ + { + "item_id": "exam-Test Resit - Introduction to Python - 22/23-1-w2-lists-and-sets", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Lists and Sets", + "subtopic_title": "", + "search_text": "Suppose you have a list called x containing tuples, where\nx = [(1, 2), (3, 4), (5, 6), (7, 8)]\n\nWhich of the following lines of code will print True?\na\nb\nc\nd\nd\nOption A evaluates to 2 * 3 == 6 (True). Option B evaluates to 3 + 5 == 8 (True). Option C evaluates to 7 - 5 == 2 (True" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "snippet_label": "Objects and Names", + "week": 1, + "topic": "Objects and Names", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-1-w1-objects-and-names", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Objects and Names", + "subtopic_title": "", + "search_text": "Suppose you already have: (i) a list of strings called europe which contain the names of all European countries, and (ii) a string variable called destination.\n\nYou want to write a program to advice Dutch residents on the documents they need to prepare before traveling:\nIf they t" + } + ] + }, + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-intro_python_sample_final_24_25-3-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "Imagine that you have a list called students, which is populated by a number of dictionaries. Each dictionary has keys: \"Name\" and \"Grade\". You'd like to print the text: [NAME] has received a grade of [GRADE], with the grade displayed to one decimal place. Which of the following " + } + ] + }, + { + "snippet_id": "item:exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "snippet_label": "Pandas Core Structures", + "week": 5, + "topic": "Pandas Core Structures", + "pieces": [ + { + "item_id": "exam-Test Exam 07-06-22-5-w5-pandas-core-structures", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Pandas Core Structures", + "subtopic_title": "", + "search_text": "You have a pandas Series called s, which contains floats. You'd like to create a new Series, in which each element is equal to the square of the difference between the corresponding element in s and the mean of the elements in s.\n\nFor example, if s is the Series:\n0 2.0\n1 " + } + ] + } + ] + } + }, + { + "evaluation_id": "round2:introduction-to-python-trial-final-exam-solutions-py22-q15", + "question_id": "introduction-to-python-trial-final-exam-solutions-py22-q15", + "exam_id": "introduction-to-python-trial-final-exam-solutions-py22", + "question_number": 15, + "status": "completed", + "question_snapshot": { + "topic": "8_Datetime_Easy_3", + "question": "Which code segment gives the same output as the following:\n\ndate1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)\n\nYou may assume that the datetime and timedelta classes are already imported from the datetime module.", + "options": { + "a": "print((datetime(2023, 5, 1) - datetime(2023, 6, 1)).days)", + "b": "print((datetime(2023, 6, 1) - datetime(2023, 1, 5)).days)", + "c": "print((datetime.strptime('2023-6-1', '%Y-%d-%m') - datetime.strptime('2023-5-1', '%Y-%d-%m')).days)", + "d": "print((datetime.strptime('2023-06-01', '%Y-%m-%d') - datetime.strptime('2023-05-01', '%Y-%m-%d')).days)" + }, + "correct": "d", + "explanation": "Option D parses ISO-style date strings using the matching '%Y-%m-%d' format and subtracts the May date from the June date, giving the same day difference as the original code.", + "code_context": "date1 = datetime(2023, 6, 1).strftime('%d-%m-%Y')\ndate2 = datetime(2023, 5, 1).strftime('%d-%m-%Y')\nprint((datetime.strptime(date1, '%d-%m-%Y') - datetime.strptime(date2, '%d-%m-%Y')).days)" + }, + "seed_context": { + "exact_match_findings": [], + "available_seed_snippet_ids": [], + "provenance_review_status": "agent_reviewed_pending_human_confirmation" + }, + "best_single_snippet": { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question." + }, + "top_three_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question." + }, + { + "item_id": "ks-b6a39f66a2", + "rationale": "Provides a very basic introduction to functions, which helps a novice understand that methods like strftime and strptime are groupings of code performing tasks." + } + ], + "minimal_sufficient_snippets": [ + { + "item_id": "exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "" + } + ], + "near_identical_past_exam_pieces": [], + "best_snippet_family": { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "This is the only snippet that directly addresses the datetime module. It explains that subtracting two datetime objects results in a timedelta and that the .days attribute provides the difference as an integer, which is crucial for understanding the 'print(...).days' part of the question.", + "critical_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + }, + "supporting_snippet_families": [ + { + "snippet_id": "item:ks-b6a39f66a2", + "rationale": "Provides a very basic introduction to functions, which helps a novice understand that methods like strftime and strptime are groupings of code performing tasks.", + "critical_piece_ids": [ + "ks-b6a39f66a2" + ] + } + ], + "minimal_snippet_families": [ + { + "snippet_id": "item:exam-intro_python_sample_final_24_25-10-w6-datetime", + "rationale": "", + "needed_piece_ids": [ + "exam-intro_python_sample_final_24_25-10-w6-datetime" + ] + } + ], + "answerability": { + "status": "partial", + "confidence": "low", + "rationale": "The available snippets explain the result of datetime subtraction and the .days attribute, but they completely lack information on strftime, strptime, and the specific formatting codes (like %d, %m, %Y) used in both the question and the options. A student without prior knowledge would be guessing the meaning of the date strings and parsing logic.", + "usable_without_prior_python_knowledge": false + }, + "gap_analysis": { + "summary": "The main gap is the lack of documentation on date string parsing and formatting.", + "missing_concepts": [ + "datetime.strptime", + "datetime.strftime", + "strftime/strptime format codes (%Y, %m, %d, %H, etc.)" + ], + "proposed_fix": "Add a lecture-style snippet or a comprehensive 'cheat sheet' piece that lists common datetime formatting codes and explains the difference between creating a string (strftime) and parsing a string (strptime)." + }, + "suggested_changes": [ + { + "kind": "add_new", + "target_item_id": "", + "proposal": "Add a 'Datetime Formatting Reference' piece from the Week 6 lecture materials. It should include: 1. datetime.strftime(format) for object -> string. 2. datetime.strptime(string, format) for string -> object. 3. A table of common codes: %Y (year), %m (month), %d (day), %H (hour), %M (minute).", + "why_helpful": "This would allow a student to decode the '1-6-2023' vs '2023-06-01' logic and verify which format string matches the date representation.", + "why_maybe_unnecessary": "If the exam is open-book and students are expected to use a general Python reference, but for a 'cheat sheet' generator, this is a core missing component.", + "recommended_direction": "add_this" + } + ], + "review_meta": { + "requires_human_review": true, + "reviewed_at": "2026-03-24T09:46:02Z", + "snippet_family_count": 395, + "model": "gemini-3-flash-preview", + "candidate_item_count": 14, + "candidate_snippet_families": [ + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Suppose you have three variables called player1_goals, player2_goals, and player3_goals. Each of the variables contains a list of integers that represents the number of goals scored by the football players in five different matches:\n\nplayer1_goals = [2, 1, 3, 2, 1]\nplayer2_goals " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called roman_nums where the keys are the integers from 1 to 5 (both are inclusive) and the values are their corresponding Roman numeral symbols.\n\nThat is, if we execute the following command:\nprint(roman_nums)\nthe output should be:\n{1: 'I', 2: 'II'" + } + ] + }, + { + "snippet_id": "item:exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Resit 22/23-7-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "Assume you already have a list of strings called words.\nYou need to create a dictionary called word_lengths, where the keys are the strings in the list words and the values are their lengths.\nWhich of the following code segments will work as intended?\na\nb\nc\nd\na\nOption A is a vali" + } + ] + }, + { + "snippet_id": "item:exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-Trial final - Introduction to Python - 22/23-4-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have to create a dictionary called vowels_ASCII where the keys are the lowercase vowels (a, e, i, o, u) and the values are their corresponding ASCII values.\nThe ASCII (American Standard Code for Information Interchange) is a character encoding standard that assigns unique num" + } + ] + }, + { + "snippet_id": "item:exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "snippet_label": "Defining and Calling Functions", + "week": 3, + "topic": "Defining and Calling Functions", + "pieces": [ + { + "item_id": "exam-Trial final exam Introduction to Python-4-w3-defining-and-calling-functions", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Defining and Calling Functions", + "subtopic_title": "", + "search_text": "You need to write a function called format_phone_number that formats phone numbers. The output of the function should be a string that represents a 10-digit number. The input argument is also a string with 10 digits, but the digits may be separated by dashes (the \"-\" character) a" + } + ] + }, + { + "snippet_id": "item:exam-midterm_2023-14-w2-loops", + "snippet_label": "Loops", + "week": 2, + "topic": "Loops", + "pieces": [ + { + "item_id": "exam-midterm_2023-14-w2-loops", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Loops", + "subtopic_title": "", + "search_text": "Assume you already have a variable called alphabet, which contains a string, e.g., alphabet = \"abcdefghijklmnopqrstuvwxyz\"\nWhich of the following code snippets will give the same output as the following command?\nprint(list(alphabet[1::2]))\nHint: The reverse() method reverses the " + } + ] + }, + { + "snippet_id": "item:exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "snippet_label": "Dictionaries and Mappings", + "week": 2, + "topic": "Dictionaries and Mappings", + "pieces": [ + { + "item_id": "exam-trial-final-exam-py22-5-w2-dictionaries-and-mappings", + "item_type": "source_exam", + "bucket": "recommended", + "topic": "Dictionaries and Mappings", + "subtopic_title": "", + "search_text": "You have two lists representing the names and ages of individuals:\nnames = ['Alice', 'Bob', 'Charlie', 'David']\nages = [25, 30, 35, 40]\n\nYou need to create a dictionary called person_dict where the keys are the names and the values are the ages.\nHowever, you want to include only " + } + ] + }, + { + "snippet_id": "item:ks-b6a39f66a2", + "snippet_label": "Functions and Imports", + "week": 1, + "topic": "Functions and Imports", + "pieces": [ + { + "item_id": "ks-b6a39f66a2", + "item_type": "source_lecture", + "bucket": "recommended", + "topic": "Functions and Imports", + "subtopic_title": "", + "search_text": "intro\n### Print is a function and tells Python to output the argument (that what is between the brackets after the function name) on your screen\n